zuul整合sentinel实现限流
效果图
一分钟以内点击三次触发限流
Setrules=new HashSet<>(); rules.add(new GatewayFlowRule("product-service").setCount(3).setIntervalSec(60)); GatewayRuleManager.loadRules(rules);
自定义限流返回结果
本次测试需要三个项目,eureka项目,product项目,zuul网关项目
父级pom
<?xml version="1.0" encoding="UTF-8"?>4.0.0 org.example zuul-aprent pom 1.0-SNAPSHOT eureka-service prodoct-service order-service zuul-service zuul-one zuul-two zuul-three zuul-sentinal org.springframework.boot spring-boot-starter-parent 2.2.5.RELEASE org.springframework.cloud spring-cloud-dependencies Hoxton.SR3 pom import com.alibaba.cloud spring-cloud-alibaba-dependencies 2.1.0.RELEASE pom import org.apache.maven.plugins maven-compiler-plugin 1.8 1.8 utf-8 org.springframework.boot spring-boot-maven-plugin
eureka项目
<?xml version="1.0" encoding="UTF-8"?>zuul-aprent org.example 1.0-SNAPSHOT 4.0.0 com.eureka eureka-service org.springframework.cloud spring-cloud-starter-netflix-eureka-server org.springframework.boot spring-boot-maven-plugin eureka
package com.eureka; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer; /** * @author yourheart * @Description * @create 2022-04-20 21:17 */ @SpringBootApplication @EnableEurekaServer public class EurekaApplication { public static void main(String[] args) { SpringApplication.run(EurekaApplication.class,args); } }
server.port=8761 spring.application.name=eureka-service eureka.instance.hostname=localhost eureka.client.service-url.defaultZone=http://localhost:8761/eureka eureka.client.register-with-eureka=false eureka.client.fetch-registry=false logging.level.com.eureka=info logging.level.web=info spring.devtools.add-properties=false
product项目
<?xml version="1.0" encoding="UTF-8"?>zuul-aprent org.example 1.0-SNAPSHOT 4.0.0 com.product prodoct-service org.springframework.cloud spring-cloud-starter-netflix-eureka-client org.springframework.boot spring-boot-starter-web com.alibaba fastjson 1.2.7 commons-lang commons-lang 2.6 org.projectlombok lombok 1.18.16 org.springframework.boot spring-boot-maven-plugin product
server.port=1000 spring.application.name=product-service #注册到eureka注册中心,如果是注册到集群就用逗号连接多个,单实例写上一个就好 eureka.client.service-url.defaultZone=http://localhost:8761/eureka logging.level.com.product=debug logging.level.web=debug spring.devtools.add-properties=false
package com.product; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.discovery.EnableDiscoveryClient; /** * @author yourheart * @Description * @create 2022-04-20 21:28 */ @SpringBootApplication @EnableDiscoveryClient public class ProductApplication { public static void main(String[] args) { SpringApplication.run(ProductApplication.class,args); } } package com.product.controller.front; import lombok.extern.slf4j.Slf4j; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; /** * @author yourheart * @Description * @create 2022-04-20 21:30 */ @RestController @RequestMapping("/product") @Slf4j public class ProductController { @GetMapping("/getProduct/{id}") public String selectProduct(@PathVariable String id){ log.info("【调用服务者入参】:{}",id); return "查询到的主键返回"+id; } @GetMapping("/testFirst/{id}") public String testFirst(@PathVariable Integer id){ log.info("【调用服务者入参】:{}",id); StringBuilder stringBuilder=new StringBuilder(); stringBuilder.append("qwe"); stringBuilder.append("-"); stringBuilder.append(id); return stringBuilder.toString(); } }
zuul项目
<?xml version="1.0" encoding="UTF-8"?>zuul-aprent org.example 1.0-SNAPSHOT 4.0.0 com.zuul zuul-sentinal org.springframework.cloud spring-cloud-starter-netflix-zuul org.springframework.cloud spring-cloud-starter-netflix-eureka-client com.alibaba.csp sentinel-zuul-adapter 1.8.2
server.port=1006 spring.application.name=zuul-sentinal #注册到eureka注册中心,如果是注册到集群就用逗号连接多个,单实例写上一个就好 eureka.client.service-url.defaultZone=http://localhost:8761/eureka logging.level.com.zuul=debug logging.level.web=debug spring.devtools.add-properties=false #设置为不支持 URL 粒度 spring.cloud.sentinel.filter.enabled=false
package com.zuul; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker; import org.springframework.cloud.client.discovery.EnableDiscoveryClient; import org.springframework.cloud.netflix.zuul.EnableZuulProxy; /** * @author yourheart * @Description * @create 2022-06-06 23:22 */ @SpringBootApplication //开启zuul注解 @EnableZuulProxy @EnableDiscoveryClient public class SentinalApplication { public static void main(String[] args) { SpringApplication.run(SentinalApplication.class,args); } } package com.zuul.exception; import com.alibaba.csp.sentinel.adapter.gateway.zuul.fallback.BlockResponse; import com.alibaba.csp.sentinel.adapter.gateway.zuul.fallback.DefaultBlockFallbackProvider; import com.alibaba.csp.sentinel.adapter.gateway.zuul.fallback.ZuulBlockFallbackProvider; import com.alibaba.csp.sentinel.log.RecordLog; import com.alibaba.csp.sentinel.slots.block.BlockException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * @author yourheart * @Description * @create 2022-06-09 0:19 */ public class MyBlockFallbackProvider implements ZuulBlockFallbackProvider { private Logger logger = LoggerFactory.getLogger(DefaultBlockFallbackProvider.class); @Override public String getRoute() { return "*"; } @Override public BlockResponse fallbackResponse(String route, Throwable cause) { RecordLog.info(String.format("[Sentinel DefaultBlockFallbackProvider] Run fallback route: %s", route)); if (cause instanceof BlockException) { return new BlockResponse(429, "Sentinel触发限流", route); } else { return new BlockResponse(500, "系统异常", route); } } } package com.zuul.filter; import com.alibaba.csp.sentinel.adapter.gateway.common.rule.GatewayFlowRule; import com.alibaba.csp.sentinel.adapter.gateway.common.rule.GatewayRuleManager; import com.alibaba.csp.sentinel.adapter.gateway.zuul.fallback.ZuulBlockFallbackManager; import com.alibaba.csp.sentinel.adapter.gateway.zuul.filters.SentinelZuulErrorFilter; import com.alibaba.csp.sentinel.adapter.gateway.zuul.filters.SentinelZuulPostFilter; import com.alibaba.csp.sentinel.adapter.gateway.zuul.filters.SentinelZuulPreFilter; import com.netflix.zuul.ZuulFilter; import com.zuul.exception.MyBlockFallbackProvider; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import javax.annotation.PostConstruct; import java.util.HashSet; import java.util.Set; /** * @author yourheart * @Description * @create 2022-06-06 23:30 */ @Configuration public class ZuulConfigFilter { @Bean public ZuulFilter sentinelZuulPreFilter(){ return new SentinelZuulPreFilter(); } @Bean public ZuulFilter sentinelZuulPostFilter(){ return new SentinelZuulPostFilter(); } @Bean public ZuulFilter sentinelZuulErrorFilter(){ return new SentinelZuulErrorFilter(); } /** * spring容器初始化调用该方法 */ @PostConstruct public void doInt(){ /** * 注册 FallbackProvider */ ZuulBlockFallbackManager.registerProvider(new MyBlockFallbackProvider()); /** * 加载网关限流规则 */ initGatewayRules(); } private void initGatewayRules(){ Setrules=new HashSet<>(); /** * 设置为60秒点击3次触发限流 */ rules.add(new GatewayFlowRule("product-service").setCount(3).setIntervalSec(60)); GatewayRuleManager.loadRules(rules); } }
测试地址http://127.0.0.1:1006/product-service/product/getProduct/1992
官方文档提供大家学习
https://github.com/alibaba/spring-cloud-alibaba/wiki/Sentinel
https://github.com/alibaba/Sentinel/wiki/%E7%BD%91%E5%85%B3%E9%99%90%E6%B5%81