SpringCloud Alibaba Sentinel---实现熔断与限流

  前言:不断学习就是程序员的宿命

一、概述

  Github官网:https://github.com/alibaba/Sentinel,就是SpringCloud的Hystrix

  下载地址:https://github.com/alibaba/Sentinel/releases

官网:https://spring-cloud-alibaba-group.github.io/github-pages/greenwich/spring-cloud-alibaba.html#spring_cloud_alibaba_sentinel

二、Sentinel 控制台

1、启动Sentinel

java -jar sentinel-dashboard-1.7.0.jar

2、登录Web界面

浏览器访问:http://localhost:8080/,用户名密码均为:sentinel

 三、Sentinel流控规则

1、流控模式

1.1直接 (默认)

1.1.1 QPS直接失败

  以下设置表示:1秒钟内查询1次就是OK,若次数超过1,就直接-快速失败,报默认错误

1.1.2线程数直接失败

1.2、关联

  当关联的资源达到阈值时,就限流自己;当与A关联的资源B达到阈值时,就限流A自己(B惹事,A挂了)

  设置:当关联资源/testB的qps阈值超过1时,就限流/testA的Rest访问地址,当关联资源达到阈值后限制配置好的资源名。

2、流控效果

  Github:https://github.com/alibaba/Sentinel/wiki/Flow-Control

2.1 直接-快速失败

  直接失败,抛出异常:Blocked by Sentinel(flow limiting)

  源码:com.alibaba.csp.sentinel.slots.block.flow.controller.DefaultController

2.2 直接-预热

  默认coldFactor为3,即请求QPS从threshold/3开始,经预热时长逐渐升至设定的QPS阈值。限流冷启动

  以下是指开始QPS为10/3=3,5秒后慢慢预热至10

2.3排队等待  

  匀速排队,阈值必须设置为QPS(漏桶算法

  源码:com.alibaba.csp.sentinel.slots.block.flow.controller.RateLimiterController

  以下设置含义:/testA每秒1次请求,超过的话就排队等待,等待的超时时间为20000毫秒。

四、Sentinel降级规则

  Github:https://github.com/alibaba/Sentinel/wiki/%E7%86%94%E6%96%AD%E9%99%8D%E7%BA%A7

   Sentinel断路器没有半开状态(Hystrix断路器是存在半开状态的)

1、RT

  以下表示:Jmeter永远1秒钟打进来10个线程(大于5,官网)调用testD,我们希望200毫米处理完本次任务。如果超过200毫秒还没处理完,在未来1秒钟的时间窗口内,断路器打开(保险丝跳闸)微服务不可用,保险丝跳闸断电。

2、异常比例

按照以下配置:

①单独访问一次,必然来一次报错一次(int a =10/0;)

②开启Jmeter,直接高并发发送请求,多次调用达到官网配置条件,断路器开启(保险丝跳闸)微服务不可用,不在报错error而是服务降级了。

3、异常数

  异常数是按照分钟统计的,访问:http://localhost:8401/testExceptionCount,第一次访问绝对报错(int a = 10/0);但是达到配置的阈值(5)次报错后,进入熔断后降级。

五、热点规则

  官网:https://github.com/alibaba/Sentinel/wiki/%E7%83%AD%E7%82%B9%E5%8F%82%E6%95%B0%E9%99%90%E6%B5%81

1、热点key限流

  配置第一个参数(索引0)阈值为1,违背则会进入Fallback兜底方法

2、参数例外项

  基于上述热点规则,期望p1参数当它为某个特殊值时,限流值与平时不太一样(例如当p1=5时,它的阈值为200)

六、系统规则

Github:https://github.com/alibaba/Sentinel/wiki/%E7%B3%BB%E7%BB%9F%E8%87%AA%E9%80%82%E5%BA%94%E9%99%90%E6%B5%81

 

 从整体维度对应用入口流量进行控制,而之前限流是细粒度对某个方法进行QPS等配置,这个是整体级别的。

七、SentinelResource配置

Github:https://github.com/alibaba/Sentinel/wiki/%E6%B3%A8%E8%A7%A3%E6%94%AF%E6%8C%81

1、按资源名限流

 关闭8401服务,查看流控规则消失,发现规则是临时的

2、按URL地址限流

3、自定义限流处理逻辑

  上述问题:

      ①系统默认的,没有体现我们自己的业务要求

      ②依照现有条件,我们自定义的处理方法又和业务代码耦合在一起,不直观

      ③每个业务方法都添加一个兜底方法,那代码膨胀

      ④全局统一的处理方法没有体现

(1)新增自定义处理方法

public class CustomerBlockHandler {

    public static CommonResult handlerException(BlockException exception) {
        return new CommonResult(444, "客户自定义,global handlerException---1");
    }

    public static CommonResult handlerException2(BlockException exception) {
        return new CommonResult(444, "客户自定义,global handlerException---2");
    }
}
View Code

(2)引用

八、Sentinel服务熔断Ribbon

1、无配置

 

 测试情况

2、配置Fallback,只负责业务异常

 

 测试情况:

3、配置blockhandler,只负责Sentinel控制台配置违规

 

 测试情况

4、配置Fallback和blockhandler

 

 测试情况:

5、异常忽略-exceptionsToIgnore

 

 

 测试情况:

九、Sentinel服务熔断OpenFeign

 1、application.yml开启对feign支持

#激活sentinel对feign的支持
feign:
  sentinel:
    enabled: true

2、主类启用注解@EnableFeignClients

3、Feign接口

 测试情况:停掉9003提供者,服务降级了

十、熔断框架比较

 

 十一、Sentinel规则持久化

  之前配置在Sentinel的规则在微服务重启,规则丢失。

  思路:将限流规则持久化进Nacos保存,只要刷新微服务的某个Rest地址,Sentinel控制台的流控规则就能看到,只要Nacos里面的配置不删除,针对某个微服务的Sentinel规则持续有效

1、application.yml添加如下配置

server:
  port: 8401
spring:
  application:
    name: cloudalibaba-sentinel-service
  cloud:
    nacos:
      discovery:
        # Nacos服务注册中心地址
        server-addr: localhost:8848
    sentinel:
      transport:
        # sentinel dashboard 地址
        dashboard: localhost:8080
        # 默认为8719,如果被占用会自动+1,直到找到为止
        port: 8719
      # 流控规则持久化到nacos
      datasource:
        dsl:
          nacos:
            server-addr: localhost:8848
            data-id: ${spring.application.name}
            group-id: DEFAULT_GROUP
            data-type: json
            rule-type: flow
management:
  endpoints:
    web:
      exposure:
        include: "*"
application.yml

2、Nacos控制台新建配置文件

  DataId为spring.application.name,json格式如下:

[
    {
        "resource":"/rateLimit/byUrl",
        "limitApp":"default",
        "grade":1,
        "count":1,
        "strategy":0,
        "controlBehavior":0,
        "clusterMode":false
    }
]

①resource:资源名称(默认请求路径)

②limitApp:来源应用默认

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

④count:单机阈值

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

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

⑦clusterMode:是否集群

3、测试情况

posted @ 2020-03-29 21:31  coder、  阅读(2019)  评论(0编辑  收藏  举报