个人随笔
目录
六、springCloudAlibaba-sentinel的熔断降级
2023-10-31 20:50:22

在上一篇文章中,我们初步体验了下sentinel的流量控制,流量控制通常都是在调用端进行控制,那么如果某一个服务每次都报错呢,那么这里我们了可以用熔断降级的策略。如果在固定时间内服务报错了规定的次数,我们就不在执行正常业务逻辑了,直接执行备用的方法,这样对系统性能和用户体验都比较好,我们来试试吧!

1、环境准备

五、springCloudAlibaba-sentinel的初步使用

2、熔断规则

  1. List<DegradeRule> degradeRules = new ArrayList<>();
  2. DegradeRule degradeRule = new DegradeRule();
  3. degradeRule.setResource(BREAK_RESOURCE_NAME);
  4. //设置规则策略,异常数
  5. degradeRule.setGrade(RuleConstant.DEGRADE_GRADE_EXCEPTION_COUNT);
  6. //触发熔断异常数:2
  7. degradeRule.setCount(2);
  8. //触发熔断最小请求数:4
  9. degradeRule.setMinRequestAmount(4);
  10. //熔断时长,单位为秒,一旦触发了熔断,再次请求对应的接口就会直接调用降级方法,这个跟之前的流量控制还是有区别的
  11. //10秒过后会变成半开的状态,恢复接口请求调用,如果第一次请求异就异常,将会再次熔断
  12. degradeRule.setTimeWindow(10);
  13. degradeRule.setStatIntervalMs(60*1000);
  14. degradeRules.add(degradeRule);
  15. DegradeRuleManager.loadRules(degradeRules);

3、请求方法

  1. @RequestMapping("/break")
  2. @SentinelResource(value = BREAK_RESOURCE_NAME, blockHandler = "exceptionHandler2")
  3. public String breakA(String id) {
  4. throw new RuntimeException("报错了");
  5. }
  6. // Block 异常处理函数,参数最后多一个 BlockException,其余与原函数一致.
  7. public String exceptionHandler2(String id, BlockException ex) {
  8. // Do some log here.
  9. // ex.printStackTrace();
  10. return "被熔断了"+id;
  11. }

4、启动测试

我们可以发现,请求第五次就返回了被熔断提示,这是因为我们设置了最小请求是4,等10s后再请求用进入了业务逻辑,此时业务逻辑还是报错,那么再次请求就继续熔断了!

5、总结

其他规则用法大体跟流量控制和熔断限流差不多,根据官网即可

6、这两节的全部代码

Controller类

  1. package com.suibibk.springCloud.order.controller;
  2. import com.alibaba.csp.sentinel.Entry;
  3. import com.alibaba.csp.sentinel.SphU;
  4. import com.alibaba.csp.sentinel.annotation.SentinelResource;
  5. import com.alibaba.csp.sentinel.slots.block.BlockException;
  6. import com.alibaba.csp.sentinel.slots.block.RuleConstant;
  7. import com.alibaba.csp.sentinel.slots.block.degrade.DegradeRule;
  8. import com.alibaba.csp.sentinel.slots.block.degrade.DegradeRuleManager;
  9. import com.alibaba.csp.sentinel.slots.block.flow.FlowRule;
  10. import com.alibaba.csp.sentinel.slots.block.flow.FlowRuleManager;
  11. import org.springframework.web.bind.annotation.RequestMapping;
  12. import org.springframework.web.bind.annotation.RestController;
  13. import javax.annotation.PostConstruct;
  14. import java.util.ArrayList;
  15. import java.util.List;
  16. @RestController
  17. @RequestMapping("/order")
  18. public class OrderController {
  19. public static final String HELLO_RESOURCE_NAME = "hello";
  20. public static final String USER_RESOURCE_NAME = "user";
  21. public static final String BREAK_RESOURCE_NAME = "break";
  22. @RequestMapping("/hello")
  23. public String hello(){
  24. // 1.5.0 版本开始可以直接利用 try-with-resources 特性
  25. try (Entry entry = SphU.entry(HELLO_RESOURCE_NAME)) {
  26. // 被保护的逻辑
  27. return "hello world";
  28. } catch (BlockException ex) {
  29. // 处理被流控的逻辑
  30. return "被限流了";
  31. }
  32. }
  33. @PostConstruct
  34. private void initFlowRules(){
  35. List<FlowRule> rules = new ArrayList<>();
  36. FlowRule rule = new FlowRule();
  37. rule.setResource(HELLO_RESOURCE_NAME);
  38. rule.setGrade(RuleConstant.FLOW_GRADE_QPS);
  39. // Set limit QPS to 20. 这里表示超过1秒的频率就会限流
  40. rule.setCount(1);
  41. rules.add(rule);
  42. FlowRule rule2 = new FlowRule();
  43. rule2.setResource(USER_RESOURCE_NAME);
  44. rule2.setGrade(RuleConstant.FLOW_GRADE_QPS);
  45. // Set limit QPS to 20. 这里表示超过1秒的频率就会限流
  46. rule2.setCount(1);
  47. rules.add(rule2);
  48. FlowRuleManager.loadRules(rules);
  49. List<DegradeRule> degradeRules = new ArrayList<>();
  50. DegradeRule degradeRule = new DegradeRule();
  51. degradeRule.setResource(BREAK_RESOURCE_NAME);
  52. //设置规则策略,异常数
  53. degradeRule.setGrade(RuleConstant.DEGRADE_GRADE_EXCEPTION_COUNT);
  54. //触发熔断异常数:2
  55. degradeRule.setCount(2);
  56. //触发熔断最小请求数:4
  57. degradeRule.setMinRequestAmount(4);
  58. //熔断时长,单位为秒,一旦触发了熔断,再次请求对应的接口就会直接调用降级方法,这个跟之前的流量控制还是有区别的
  59. //10秒过后会变成半开的状态,恢复接口请求调用,如果第一次请求异就异常,将会再次熔断
  60. degradeRule.setTimeWindow(10);
  61. degradeRule.setStatIntervalMs(60*1000);
  62. degradeRules.add(degradeRule);
  63. DegradeRuleManager.loadRules(degradeRules);
  64. }
  65. /**
  66. * exceptionHandler :被流控降级的方法,默认该方法必须声明在同一个类中,一定是public,返回值跟原方法一致
  67. * @param id
  68. * @return
  69. */
  70. @RequestMapping("/user")
  71. @SentinelResource(value = USER_RESOURCE_NAME, blockHandler = "exceptionHandler")
  72. public String user(String id) {
  73. return "返回用户成功"+id;
  74. }
  75. // Block 异常处理函数,参数最后多一个 BlockException,其余与原函数一致.
  76. public String exceptionHandler(String id, BlockException ex) {
  77. // Do some log here.
  78. ex.printStackTrace();
  79. return "被限流了"+id;
  80. }
  81. @RequestMapping("/break")
  82. @SentinelResource(value = BREAK_RESOURCE_NAME, blockHandler = "exceptionHandler2")
  83. public String breakA(String id) {
  84. throw new RuntimeException("报错了");
  85. }
  86. // Block 异常处理函数,参数最后多一个 BlockException,其余与原函数一致.
  87. public String exceptionHandler2(String id, BlockException ex) {
  88. // Do some log here.
  89. // ex.printStackTrace();
  90. return "被熔断了"+id;
  91. }
  92. }

启动类

  1. package com.suibibk.springCloud.order;
  2. import com.alibaba.csp.sentinel.annotation.aspectj.SentinelResourceAspect;
  3. import org.springframework.boot.SpringApplication;
  4. import org.springframework.boot.autoconfigure.SpringBootApplication;
  5. import org.springframework.context.annotation.Bean;
  6. /**
  7. * Hello world!
  8. */
  9. @SpringBootApplication
  10. public class OrderApplication {
  11. public static void main( String[] args ) {
  12. SpringApplication.run(OrderApplication.class,args);
  13. }
  14. @Bean
  15. public SentinelResourceAspect sentinelResourceAspect(){
  16. return new SentinelResourceAspect();
  17. }
  18. }
 37

啊!这个可能是世界上最丑的留言输入框功能~


当然,也是最丑的留言列表

有疑问发邮件到 : suibibk@qq.com 侵权立删
Copyright : 个人随笔   备案号 : 粤ICP备18099399号-2