• Sentinel规则


    一、服务熔断测试

    例子:

    application.properties配置文件

    server.port=8083
    
    spring.application.name=order
    
    #spring.cloud.nacos.discovery.server-addr=http://192.168.44.64:80
    
    spring.cloud.nacos.discovery.server-addr=localhost:8848
    
    spring.cloud.sentinel.transport.port=9999
    
    spring.cloud.sentinel.transport.dashboard=localhost:8888
    
    spring.cloud.sentinel.web-context-unify=false

    自定义业务类CustomerBlockHandler

    1. public class CustomerBlockHandler {
    2. public static ResponseMsg handlerException(BlockException exception) {
    3. return new ResponseMsg(404, "自定义1111111111111");
    4. }
    5. }

     controller类

    1. @RestController
    2. @RequestMapping
    3. public class Test2Controller {
    4. @GetMapping("/t1")
    5. @SentinelResource(value = "CustomerBlockHandler",
    6. blockHandlerClass = CustomerBlockHandler.class,
    7. blockHandler = "handlerException")
    8. public ResponseMsg t1(){
    9. return ResponseMsg.SUCCESS(200,"成功",null);
    10. }
    11. }

    Sentinel配置

    二、配置流控效果

    1. 快速失败(默认)

    直接失败,抛出异常,不做任何额外的处理,是最简单的效果

    2. Warm Up

    它从开始阈值到最大QPS阈值会有一个缓冲阶段,一开始的阈值是最大QPS阈值的1/3,然后慢慢.增长,直到最大阈值,适用于将突然增大的流量转换为缓步增长的场景

    例子:

    Controller类

    1. @GetMapping("/t2")
    2. public ResponseMsg t2(){
    3. return ResponseMsg.SUCCESS(200,"成功",null);
    4. }

     Sentinel配置

    设置阈值为 10,预热时间是 5 秒,逐渐增加到阈值上限,所以会有一个初始阈值

    初始阈值 = 阈值上限 / coldFactor, coldFactor 是冷加载因子,默认为3

    上面这个配置的效果就是:在 5 秒内最大阈值是 3(10/codeFactor),超过5秒,最大阈值为10

    3.  排队等待

    让请求以均匀的速度通过,单机阈值为每秒通过数量,其余的排队等待; 它还会让设置一个超时时间,当请求超过超时间时间还未处理,则会被丢弃

    排队等待方式会严格控制请求通过的间隔时间,也即是让请求以均匀的速度通过,对应的是漏桶算法。

    注意:匀速排队,让请求以匀速通过,阈值类型必须设置为QPS,否则无效,匀速排队模式暂时不支持 QPS > 1000 的场景

    例子:

    Controller

    1. @GetMapping("/t3")
    2. public ResponseMsg t3(){
    3. return ResponseMsg.SUCCESS(200,"成功",null);
    4. }
      Sentinel配置

    当阈值设为 2 的时候,则代表一秒匀速的通过 2 个请求,也就是每个请求平均间隔恒定为 1000 / 2 = 500 ms,每一个请求的最长等待时间(maxQueueingTimeMs)为 0.5s 。

    三、降级规则

    降级规则就是设置当满足什么条件的时候,对服务进行降级

    慢调用比例

    例子:

    Controller

     

    1. @GetMapping("/t4")
    2. public ResponseMsg t4(){
    3. try {
    4. Thread.sleep(600);//线程睡眠600毫秒
    5. } catch (InterruptedException e) {
    6. throw new RuntimeException(e);
    7. }
    8. return ResponseMsg.SUCCESS(200,"成功",null);
    9. }
     Sentinel配置

     

     测试

    这样在5秒内查询的结果一直为空

    异常比例

    当资源的每秒请求量>=5,并且每秒异常总数占通过量的比值超过阈值之后,资源进入降级状态,即在接下的时间窗口智能,对这个方法的调用都会自动地返回。异常比率的阈值范围是[0.0,1.0],代表0%~100%

    例子:

    Controller

    1. @GetMapping("/t5")
    2. public ResponseMsg t5(){
    3. System.out.println(1/0);
    4. return ResponseMsg.SUCCESS(200,"成功",null);
    5. }
    Sentinel配置

    测试

    异常数

    跟异常比例基本上一样

    例子:

    Controller

     

    1. @GetMapping("/t5")
    2. public ResponseMsg t5(){
    3. System.out.println(1/0);
    4. return ResponseMsg.SUCCESS(200,"成功",null);
    5. }
    Sentinel配置

    测试

    四、热点规则

    热点参数流控规则是一种更细粒度的流控规则, 它允许将规则具体到参数上。

    热点规则普通使用

    Controller

    1. @GetMapping("/t6")
    2. @SentinelResource(value = "test6")
    3. //注意这里必须使用这个注解标识,热点规则不生效
    4. public ResponseMsg t6(String str , Integer number){
    5. return ResponseMsg.SUCCESS(number,"成功",str);
    6. }

    Sentinel配置

    测试 

    热点规则增强使用

    controller

    跟上面的普通使用一样

    1. @GetMapping("/t6")
    2. @SentinelResource(value = "test6")
    3. //注意这里必须使用这个注解标识,热点规则不生效
    4. public ResponseMsg t6(String str , Integer number){
    5. return ResponseMsg.SUCCESS(number,"成功",str);
    6. }

    Sentinel配置

    测试

    五、授权规则

    很多时候,我们需要根据调用来源来判断该次请求是否允许放行,这时候可以使用 Sentinel 的来源 访问控制的功能。来源访问控制根据资源的请求来源(origin)限制资源是否通过: 若配置白名单,则只有请求来源位于白名单内时才可通过; 若配置黑名单,则请求来源位于黑名单时不通过,其余的请求通过

    例子:

    自定义来源处理规则

    1. @Component
    2. public class RequestOriginParserDefinition implements RequestOriginParser {
    3. @Override
    4. public String parseOrigin(HttpServletRequest request) {
    5. String serviceName = request.getParameter("serviceName");
    6. return serviceName;
    7. }
    8. }

     

    Controller

    1. @GetMapping("/t7")
    2. public ResponseMsg t7(String str , Integer number){
    3. return ResponseMsg.SUCCESS(number,"成功",str);
    4. }

    Sentinel配置

    测试

     

     

    黑名单同样如此  只不过携带的参数是设置的参数将被拦截

    六、全局异常的返回

    异常配置类

    1. @ControllerAdvice//全局异常
    2. public class Test2Exception {
    3. @ResponseBody
    4. @ExceptionHandler({Exception.class})
    5. public ResponseMsg test(){
    6. return new ResponseMsg(500,"错误!!!!!");
    7. }
    8. }

    controller

     

    1. @GetMapping("/t5")
    2. public ResponseMsg t5(){
    3. System.out.println(1/0);
    4. return ResponseMsg.SUCCESS(200,"成功",null);
    5. }

    测试

     

    七、Sentinel规则持久化

    以通过Dashboard来为每个Sentinel客户端设置各种各样的规则,但是这里有一个问题,就是这些规则默认是存放在内存中,极不稳定,所以需要将其持久化。

    方法一

    添加到nacos里面

    在配置文件application中添加以下内容

    spring.cloud.sentinel.datasource.ds1.nacos.data-id=${spring.application.name}

    spring.cloud.sentinel.datasource.ds1.nacos.data-type=json

    spring.cloud.sentinel.datasource.ds1.nacos.server-addr=localhost:8848

    spring.cloud.sentinel.datasource.ds1.nacos.group-id=DEFAULT_GROUP

    spring.cloud.sentinel.datasource.ds1.nacos.rule-type=flow

     在nacos中为cloudalibaba-sentinel-service(可以在配置文件自定义)服务添加对应配置。

    [

            {

                    "resource": "/rateLimit/customerBlockHandler",#/rateLimit/customerBlockHandler

                    "limitApp": "default",

                    "grade": 1,

                    "count": 1,

                    "strategy": 0,

                    "controlBehavior": 0,

                    "clusterMode": false

            }

    ]

    resource: 资源名称;

    imitApp: 来源应用;

    grade: 阈值类型,0表示线程数,1表示QPS;

    count: 单机阈值;

    strategy: 流控模式,0表示直接,1表示关联,2表示链路;

    controlBehavior: 流控效果,0表示快速失败,1表示。Warm Up,2表示排队等待。

    clusterMode: 是否集群。

     

    方法二

    使用文件

    先创建一个FilePersistence类

    1. import com.alibaba.csp.sentinel.command.handler.ModifyParamFlowRulesCommandHandler;
    2. import com.alibaba.csp.sentinel.datasource.*;
    3. import com.alibaba.csp.sentinel.init.InitFunc;
    4. import com.alibaba.csp.sentinel.slots.block.authority.AuthorityRule;
    5. import com.alibaba.csp.sentinel.slots.block.authority.AuthorityRuleManager;
    6. import com.alibaba.csp.sentinel.slots.block.degrade.DegradeRule;
    7. import com.alibaba.csp.sentinel.slots.block.degrade.DegradeRuleManager;
    8. import com.alibaba.csp.sentinel.slots.block.flow.FlowRule;
    9. import com.alibaba.csp.sentinel.slots.block.flow.FlowRuleManager;
    10. import com.alibaba.csp.sentinel.slots.block.flow.param.ParamFlowRule;
    11. import com.alibaba.csp.sentinel.slots.block.flow.param.ParamFlowRuleManager;
    12. import com.alibaba.csp.sentinel.slots.system.SystemRule;
    13. import com.alibaba.csp.sentinel.slots.system.SystemRuleManager;
    14. import com.alibaba.csp.sentinel.transport.util.WritableDataSourceRegistry;
    15. import com.alibaba.fastjson.JSON;
    16. import com.alibaba.fastjson.TypeReference;
    17. import org.springframework.beans.factory.annotation.Value;
    18. import java.io.File;
    19. import java.io.IOException;
    20. import java.util.List;
    21. public class FilePersistence implements InitFunc {
    22. @Value("${spring.application.name}")
    23. private String appcationName;
    24. @Override
    25. public void init() throws Exception {
    26. String ruleDir = System.getProperty("user.home") + "/sentinel-rules/" + appcationName;
    27. String flowRulePath = ruleDir + "/flow-rule.json";
    28. String degradeRulePath = ruleDir + "/degrade-rule.json";
    29. String systemRulePath = ruleDir + "/system-rule.json";
    30. String authorityRulePath = ruleDir + "/authority-rule.json";
    31. String paramFlowRulePath = ruleDir + "/param-flow-rule.json";
    32. this.mkdirIfNotExits(ruleDir);
    33. this.createFileIfNotExits(flowRulePath);
    34. this.createFileIfNotExits(degradeRulePath);
    35. this.createFileIfNotExits(systemRulePath);
    36. this.createFileIfNotExits(authorityRulePath);
    37. this.createFileIfNotExits(paramFlowRulePath);
    38. // 流控规则
    39. ReadableDataSource> flowRuleRDS = new FileRefreshableDataSource<>(
    40. flowRulePath,
    41. flowRuleListParser
    42. );
    43. FlowRuleManager.register2Property(flowRuleRDS.getProperty());
    44. WritableDataSource> flowRuleWDS = new FileWritableDataSource<>(
    45. flowRulePath,
    46. this::encodeJson
    47. );
    48. WritableDataSourceRegistry.registerFlowDataSource(flowRuleWDS);
    49. // 降级规则
    50. ReadableDataSource> degradeRuleRDS = new FileRefreshableDataSource<>(
    51. degradeRulePath,
    52. degradeRuleListParser
    53. );
    54. DegradeRuleManager.register2Property(degradeRuleRDS.getProperty());
    55. WritableDataSource> degradeRuleWDS = new FileWritableDataSource<>(
    56. degradeRulePath,
    57. this::encodeJson
    58. );
    59. WritableDataSourceRegistry.registerDegradeDataSource(degradeRuleWDS);
    60. // 系统规则
    61. ReadableDataSource> systemRuleRDS = new FileRefreshableDataSource<>(
    62. systemRulePath,
    63. systemRuleListParser
    64. );
    65. SystemRuleManager.register2Property(systemRuleRDS.getProperty());
    66. WritableDataSource> systemRuleWDS = new FileWritableDataSource<>(
    67. systemRulePath,
    68. this::encodeJson
    69. );
    70. WritableDataSourceRegistry.registerSystemDataSource(systemRuleWDS);
    71. // 授权规则
    72. ReadableDataSource> authorityRuleRDS = new FileRefreshableDataSource<>(
    73. authorityRulePath,
    74. authorityRuleListParser
    75. );
    76. AuthorityRuleManager.register2Property(authorityRuleRDS.getProperty());
    77. WritableDataSource> authorityRuleWDS = new FileWritableDataSource<>(
    78. authorityRulePath,
    79. this::encodeJson
    80. );
    81. WritableDataSourceRegistry.registerAuthorityDataSource(authorityRuleWDS);
    82. // 热点参数规则
    83. ReadableDataSource> paramFlowRuleRDS = new FileRefreshableDataSource<>(
    84. paramFlowRulePath,
    85. paramFlowRuleListParser
    86. );
    87. ParamFlowRuleManager.register2Property(paramFlowRuleRDS.getProperty());
    88. WritableDataSource> paramFlowRuleWDS = new FileWritableDataSource<>(
    89. paramFlowRulePath,
    90. this::encodeJson
    91. );
    92. ModifyParamFlowRulesCommandHandler.setWritableDataSource(paramFlowRuleWDS);
    93. }
    94. private Converter> flowRuleListParser = source -> JSON.parseObject(
    95. source,
    96. new TypeReference>() {
    97. }
    98. );
    99. private Converter> degradeRuleListParser = source -> JSON.parseObject(
    100. source,
    101. new TypeReference>() {
    102. }
    103. );
    104. private Converter> systemRuleListParser = source -> JSON.parseObject(
    105. source,
    106. new TypeReference>() {
    107. }
    108. );
    109. private Converter> authorityRuleListParser = source -> JSON.parseObject(
    110. source,
    111. new TypeReference>() {
    112. }
    113. );
    114. private Converter> paramFlowRuleListParser = source -> JSON.parseObject(
    115. source,
    116. new TypeReference>() {
    117. }
    118. );
    119. private void mkdirIfNotExits(String filePath) throws IOException {
    120. File file = new File(filePath);
    121. if (!file.exists()) {
    122. file.mkdirs();
    123. }
    124. }
    125. private void createFileIfNotExits(String filePath) throws IOException {
    126. File file = new File(filePath);
    127. if (!file.exists()) {
    128. file.createNewFile();
    129. }
    130. }
    131. private String encodeJson(T t) {
    132. return JSON.toJSONString(t);
    133. }
    134. }
    在对应的微服务下面的resources里面创一个目录

    写上刚才的配置类位置

    这样每次设置的配置项目重启都不会清空了

  • 相关阅读:
    Sealos CLI快速部署部署K8s集群
    7-7 六度空间
    MATLAB算法实战应用案例精讲-【图像处理】目标检测(附实战案例及代码实现)
    Docker_基础知识
    数据结构与算法面试
    106 基于消息队列来做 mysql 大数据表数据的遍历处理
    缓存击穿、缓存穿透、缓存雪崩、反向代理的概念
    【Pytorch笔记】3.数学运算
    风力发电机液压偏航控制系统设计
    torch.optim.Adam() 函数用法
  • 原文地址:https://blog.csdn.net/weixin_68193389/article/details/134440659