SpringCloud Alibaba Sentinel实现熔断与限流------服务熔断功能
sentinel整合ribbon+openFeign+fallback
一、Ribbon系列
1、启动nacos和sentinel
2、新建Module
cloudalibaba-provider-payment9003
cloudalibaba-provider-payment9004
业务类代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | @RestController public class PaymentController { @Value("${server.port}") private String serverPort; public static HashMap< Long , Payment> hashMap = new HashMap<>(); static { hashMap.put(1L,new Payment(1L,"28a8c1e3bc2742d8848569891fb42181")); hashMap.put(2L,new Payment(2L,"bba8c1e3bc2742d8848569891ac32182")); hashMap.put(3L,new Payment(3L,"6ua8c1e3bc2742d8848569891xt92183")); } @GetMapping(value = "/paymentSQL/{id}") public CommonResult< Payment > paymentSQL(@PathVariable("id") Long id) { Payment payment = hashMap.get(id); CommonResult< Payment > result = new CommonResult(200,"from mysql,serverPort: "+serverPort,payment); return result; } } |
3、新建消费者Module
cloudalibaba-consumer-nacos-order84
业务类 CircleBreakerController
目的测试 : fallback管运行异常 blockHandler管配置违规
1、没有任何配置 --- 给客户error页面,不友好
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | @RestController @Slf4j public class CircleBreakerController { public static final String SERVICE_URL = "http://nacos-payment-provider"; @Resource private RestTemplate restTemplate; @RequestMapping("/consumer/fallback/{id}") @SentinelResource(value = "fallback") public CommonResult< Payment > fallback(@PathVariable Long id) { CommonResult< Payment > result = restTemplate.getForObject(SERVICE_URL + "/paymentSQL/"+id,CommonResult.class,id); if (id == 4) { throw new IllegalArgumentException ("IllegalArgumentException,非法参数异常...."); }else if (result.getData() == null) { throw new NullPointerException ("NullPointerException,该ID没有对应记录,空指针异常"); } return result; } } |
2、只配置fallback
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | @RestController @Slf4j public class CircleBreakerController { public static final String SERVICE_URL = "http://nacos-payment-provider"; @Resource private RestTemplate restTemplate; @RequestMapping("/consumer/fallback/{id}") @SentinelResource(value = "fallback",fallback = "handlerFallback") //fallback负责业务异常 public CommonResult< Payment > fallback(@PathVariable Long id) { CommonResult< Payment > result = restTemplate.getForObject(SERVICE_URL + "/paymentSQL/"+id,CommonResult.class,id); if (id == 4) { throw new IllegalArgumentException ("IllegalArgumentException,非法参数异常...."); }else if (result.getData() == null) { throw new NullPointerException ("NullPointerException,该ID没有对应记录,空指针异常"); } return result; } public CommonResult handlerFallback(@PathVariable Long id,Throwable e) { Payment payment = new Payment(id,"null"); return new CommonResult<>(444,"兜底异常handlerFallback,exception内容 "+e.getMessage(),payment); } } |
3、只配置blockHandler
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | @RestController @Slf4j public class CircleBreakerController { public static final String SERVICE_URL = "http://nacos-payment-provider"; @Resource private RestTemplate restTemplate; @RequestMapping("/consumer/fallback/{id}") @SentinelResource(value = "fallback",blockHandler = "blockHandler") //blockHandler负责在sentinel里面配置的降级限流 public CommonResult< Payment > fallback(@PathVariable Long id) { CommonResult< Payment > result = restTemplate.getForObject(SERVICE_URL + "/paymentSQL/"+id,CommonResult.class,id); if (id == 4) { throw new IllegalArgumentException ("非法参数异常...."); }else if (result.getData() == null) { throw new NullPointerException ("NullPointerException,该ID没有对应记录"); } return result; } public CommonResult handlerFallback(@PathVariable Long id,Throwable e) { Payment payment = new Payment(id,"null"); return new CommonResult<>(444,"fallback,无此流水,exception "+e.getMessage(),payment); } public CommonResult blockHandler(@PathVariable Long id,BlockException blockException) { Payment payment = new Payment(id,"null"); return new CommonResult<>(445,"blockHandler-sentinel限流,无此流水: blockException "+blockException.getMessage(),payment); } |
4、fallback和blockHandler都配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | @RestController @Slf4j public class CircleBreakerController { public static final String SERVICE_URL = "http://nacos-payment-provider"; @Resource private RestTemplate restTemplate; @RequestMapping("/consumer/fallback/{id}") @SentinelResource(value = "fallback",fallback = "handlerFallback",blockHandler = "blockHandler") public CommonResult< Payment > fallback(@PathVariable Long id) { CommonResult< Payment > result = restTemplate.getForObject(SERVICE_URL + "/paymentSQL/"+id,CommonResult.class,id); if (id == 4) { throw new IllegalArgumentException ("非法参数异常...."); }else if (result.getData() == null) { throw new NullPointerException ("NullPointerException,该ID没有对应记录"); } return result; } public CommonResult handlerFallback(@PathVariable Long id,Throwable e) { Payment payment = new Payment(id,"null"); return new CommonResult<>(444,"fallback,无此流水,exception "+e.getMessage(),payment); } public CommonResult blockHandler(@PathVariable Long id,BlockException blockException) { Payment payment = new Payment(id,"null"); return new CommonResult<>(445,"blockHandler-sentinel限流,无此流水: blockException "+blockException.getMessage(),payment); } |
结果
若 blockHandler 和 fallback 都进行了配置,则被限流降级而抛出 BlockException 时只会进入 blockHandler 处理逻辑。
5、忽略属性 exceptionsToIgnore
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | @RestController @Slf4j public class CircleBreakerController { public static final String SERVICE_URL = "http://nacos-payment-provider"; @Resource private RestTemplate restTemplate; @RequestMapping("/consumer/fallback/{id}") @SentinelResource(value = "fallback", fallback = "handlerFallback", blockHandler = "blockHandler", exceptionsToIgnore = {IllegalArgumentException.class}) public CommonResult< Payment > fallback(@PathVariable Long id) { CommonResult< Payment > result = restTemplate.getForObject(SERVICE_URL + "/paymentSQL/"+id,CommonResult.class,id); if (id == 4) { throw new IllegalArgumentException ("非法参数异常...."); }else if (result.getData() == null) { throw new NullPointerException ("NullPointerException,该ID没有对应记录"); } return result; } public CommonResult handlerFallback(@PathVariable Long id,Throwable e) { Payment payment = new Payment(id,"null"); return new CommonResult<>(444,"fallback,无此流水,exception "+e.getMessage(),payment); } public CommonResult blockHandler(@PathVariable Long id,BlockException blockException) { Payment payment = new Payment(id,"null"); return new CommonResult<>(445,"blockHandler-sentinel限流,无此流水: blockException "+blockException.getMessage(),payment); } } |
二、Feign系列
修改84消费者模块
1、pom.xml
1 2 3 4 5 | <!--SpringCloud openfeign --> < dependency > < groupId >org.springframework.cloud</ groupId > < artifactId >spring-cloud-starter-openfeign</ artifactId > </ dependency > |
2、application.yml
1 2 3 4 | # 激活Sentinel对Feign的支持 feign: sentinel: enabled: true |
3、带@FeignClient注解的业务类
1 2 3 4 5 6 | @FeignClient(value = "nacos-payment-provider",fallback = PaymentFallbackService.class)//调用中关闭9003服务提供者 public interface PaymentService { @GetMapping(value = "/paymentSQL/{id}") public CommonResult< Payment > paymentSQL(@PathVariable("id") Long id); }< br >< br > |
1 2 3 4 5 6 7 8 9 | @Component public class PaymentFallbackService implements PaymentService { @Override public CommonResult< Payment > paymentSQL(Long id) { return new CommonResult<>(444,"服务降级返回,没有该流水信息",new Payment(id, "errorSerial......")); } } |
4、CircleBreakerController
1 2 3 4 5 6 7 8 9 10 11 12 13 | //==================OpenFeign @Resource private PaymentService paymentService; @GetMapping(value = "/consumer/openfeign/{id}") public CommonResult< Payment > paymentSQL(@PathVariable("id") Long id) { if(id == 4) { throw new RuntimeException("没有该id"); } return paymentService.paymentSQL(id); } |
5、主启动类
1 2 3 4 5 6 7 8 9 | @EnableDiscoveryClient @SpringBootApplication @EnableFeignClients public class OrderNacosMain84 { public static void main(String[] args) { SpringApplication.run(OrderNacosMain84.class, args); } } |
6、测试结果
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)