SpringCloud13-Sentinel

SpringCloud13-Sentinel

1.Sentinel

  1. 从流量控制、熔断降级、系统负载保护等多个维度保护服务的稳定性。
  2. Spring官网文档地址。https://spring-cloud-alibaba-group.github.io/github-pages/hoxton/en-us/index.html#_spring_cloud_alibaba_sentinel
  3. Sentinel官网地址。https://sentinelguard.io/zh-cn/docs/introduction.html
  4. GitHub源码地址。https://github.com/alibaba/Sentinel

2.Sentinel下载、安装和运行。

  1. Sentinel下载地址。https://github.com/alibaba/Sentinel/releases
  2. 运行Sentinel,需要使用 8080端口,所以运行时需要保证 8080不能被占用。运行命令java -jar sentinel-dashboard-1.8.2.jar
  3. 访问地址。http://localhost:8080

3.创建微服务cloud-nacos-sentinel-service8401

  1. pom.xml。
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
  1. yml
server:
  port: 8401

spring:
  application:
    name: cloud-nacos-sentinel-service
  cloud:
    nacos:
      discovery:
        server-addr: http://127.0.0.1:8848
    sentinel:
      transport:
        #配置Sentinel dashboard地址
        dashboard: http://127.0.0.1:8080
        port: 8719
  1. Main和业务类不变。

  2. Sentinel采用的懒加载说明,没有访问,在Sentinel中是不会显示的请求的,所以执行一次访问。

4.Sentinel流控规则

  1. 资源名:唯一名称,默认请求路径。
  2. 阈值类型/单机阈值:QPS(每秒钟的请求数量)︰当调用该API的QPS达到阈值的时候,进行限流;线程数:当调用该API的线程数达到阈值的时候,进行限流。
  3. 流控模式。
    1. 直接:API达到限流条件时,直接限流。
    2. 关联:当关联的资源达到阈值时,就限流自己。
    3. 链路:只记录指定链路上的流量(指定资源从入口资源进来的流量,如果达到阈值,就进行限流)【API级别的针对来源】。
  4. 流控效果。
    1. 快速失败:直接失败,抛异常。
    2. Warm up:根据Code Factor(冷加载因子,默认3)的值,从阈值/codeFactor,经过预热时长,才达到设置的QPS阈值。
    3. 排队等待:匀速排队,让请求以匀速的速度通过,阈值类型必须设置为QPS,否则无效。

5.Sentinel流控规则的具体使用

  1. 限制QPS阈值类型:QPS;单机阈值:1,即每秒只处理一个请求;流控模式:直接,当前访问的路径达到阈值,直接限流;流控效果:快速失败。

效果:当每秒访问的请求超过1次,返回错误信息Blocked by Sentinel (flow limiting)。

  1. 限制线程数。阈值类型:线程数;单机阈值:1;流控模式:直接;流控效果:无。

效果:当前请求路径值允许一个线程处理请求,当这个线程正在处理请求时,有其他的请求过来,直接报错。Blocked by Sentinel (flow limiting)

  1. 关联。阈值类型:QPS;单机阈值:1;流控模式:关联/testB;流控效果:快速失败。

效果:当/testBQPS打到阈值时,每秒超过1次,/testA快速失败,返回Blocked by Sentinel (flow limiting)。

默认流控效果的源码,com.alibaba.csp.sentinel.slots.block.flow.controller.DefaultController

  1. 预热。阈值类型:QPS;单机阈值:10;流控模式:直接;流控效果:Warm Up, 5。

开始时QPS为10/3(默认)=3,超过3,报错Blocked by Sentinel (flow limiting)。5秒后,QPS可以达到10。

源码,com.alibaba.csp.sentinel.slots.block.flow.controller.WarmUpController

  1. 排队等候,匀速通过。阈值类型:QPS;单机阈值:1;流控模式:直接;流控效果:排队等候, 超时时间 20000。

就是有多个请求同时过来,匀速每秒处理一个请求,超时,报错Blocked by Sentinel (flow limiting)。注意:匀速排队模式暂时不支持 QPS > 1000 的场景。

6.Sentinel熔断规则

  1. 熔断策略:慢调用比例;最大RT:200ms;比例阈值:0.5,熔断时长:5s;最小请求:5;统计时长:1000ms。

配置解释:对/testC配置服务降级策略,1000ms内通过了5个请求,并且5个请求有50%的请求时间高于200ms,则打开断路器,进行服务熔断。5妙后,断路器进入半开状态。放入一个请求,请求时间在200ms内,则关闭断路器,正常提供服务。否则,继续打开断路器,5秒后断路器再次进入半开状态。

  1. 资源名:/testC;熔断策略:异常比例;比例阈值:0.5,熔断时长:5s,最小请求:5;统计时长:1000ms。

配置解释:1000ms内通过了5个请求,并且5个请求有50%的请求出现异常,则打开断路器,进行服务熔断,5妙后,断路器进入半开状态。放入一个请求,没有出现异常,则关闭断路器,正常提供服务。否则,继续打开断路器,5秒后断路器再次进入半开状态。

  1. 熔断策略:异常数;异常数:5;熔断时长:5s,最小请求:5;统计时长:1000ms。

配置解释:1000ms内通过了5个请求,并且5个请求有5个请求出现异常,则打开断路器,进行服务熔断,5妙后,断路器进入半开状态。放入一个请求,没有出现异常,则关闭断路器,正常提供服务。否则,继续打开断路器,5秒后断路器再次进入半开状态。

7. @SentinelResource注解

  1. @SentinelResource(value = "hotkey", blockHandler = "blockHandler", fallback = "fallback")。
  2. value = "hotkey"解释,在Sentinel控制台配置时,可以使用value的值,需要保证value唯一。
  3. blockHandler = "blockHandler",出现违反SentinelDashboard配置规则的兜底方法,程序运行异常不会采用这个兜底方法。
  4. fallback = "fallback",程序运行时异常的兜底方法,违反SentinelDashboard 配置规则不会使用这个兜底方法。
  5. 自定义全局配置兜底方法。@SentinelResource(value = "customer", blockHandlerClass = CustomerBlockHandler.class, blockHandler = "handle01"),当前方法的限流处理,使用CustomerBlockHandler的handle01方法。
  6. @SentinelResource(value = "get", fallback = "fallback", exceptionsToIgnore = {IllegalArgumentException.class}),忽略IllegalArgumentException异常信息,即不会对程序抛出的IllegalArgumentException异常调用兜底方法,而是直接返回Error Page。

8.热点key配置规则

  1. 资源名:hotkey;限流模式:QPS模式;参数索引:0,value = "hotkey",方法的第一个参数。会对每次访问带第一个参数的请求进行统计,如果没有带第一个参数不会进行统计;单机阈值:1;统计窗口时长:1s。

配置解释:1s中带着第一个参数访问的请求,不能超过1次,超过一次返回@SentinelResource中定义的兜底方法。

  1. 热点key高级配置-参数列外项。热点规则同上;参数例外项:参数类型:java.lang.String;参数值:10;限流阈值:100。

配置解释:1s中带着第一个参数访问的请求超过1次,进行服务降级;但是如果第一个参数的值为10,阈值可以打到100,即参数值为5,一秒钟支持访问100次。

9.Sentinel系统配置规则

  1. Sentinel系统自适应限流从整体维度对应用入口流量进行控制,结合应用的Load、CPU 使用率、总体平均RT、入口QPS 和并发线程数等几个维度的监控指标,通过自适应的流控策略,让系统的入口流量和系统的负载达到一个平衡,让系统尽可能跑在最大吞吐量的同时保证系统整体的稳定性。
  2. 系统规则的具体配置。
    1. Load 自适应(仅对 Linux/Unix-like 机器生效):系统的 load1 作为启发指标,进行自适应系统保护。当系统 load1 超过设定的启发值,且系统当前的并发线程数超过估算的系统容量时才会触发系统保护(BBR 阶段)。系统容量由系统的 maxQps * minRt 估算得出。设定参考值一般是 CPU cores * 2.5。
    2. CPU usage(1.5.0+ 版本):当系统 CPU 使用率超过阈值即触发系统保护(取值范围 0.0-1.0),比较灵敏。
    3. 平均 RT:当单台机器上所有入口流量的平均 RT 达到阈值即触发系统保护,单位是毫秒。
    4. 并发线程数:当单台机器上所有入口流量的并发线程数达到阈值即触发系统保护。
    5. 入口 QPS:当单台机器上所有入口流量的 QPS 达到阈值即触发系统保护。

10.Sentinel整合OpenFeign进行远程调用

  1. 创建微服务cloud-nacos-provider-payment9003和cloud-nacos-provider-payment9004,作为生成者。pom.xml、yml、Main和业务类保持不变。

  2. 创建微服务cloud-nacos-consumer-order84作为消费者,通过OpenFeign+LoadBalance调用9003和9004。

    1. pom.xml
    <!--SpringCloud openfeign -->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-openfeign</artifactId>
    </dependency>
    <!--SpringCloud ailibaba nacos -->
    <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
    </dependency>
    
    <!-- 新版本的Nacos没有引入Ribbon,需要手动引入loadbalancer进行负载均衡 -->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-loadbalancer</artifactId>
    </dependency>
    <!--SpringCloud ailibaba sentinel -->
    <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
    </dependency>
    
    1. yml
    # 开启feign对Sentinel的支持
    feign:
      sentinel:
        enabled: true
    
    1. Main
    @EnableFeignClients // 添加Feign的注解
    @EnableDiscoveryClient
    @SpringBootApplication
    public class CloudNacosConsumerOrder84Main {
    
        public static void main(String[] args) {
            SpringApplication.run(CloudNacosConsumerOrder84Main.class, args);
        }
    }
    
    1. controller
    @Slf4j
    @RestController
    public class OrderController {
    
        /**
         * 需要注意,OpenFeign会通过代理,生成IPaymentService接口的实现类。而我们又将
         * IPaymentService的实现类PaymentService,兜底的方法注入容器,
         * 所以这里的属性名需要时 iPaymentService,和接口保值一致。
         * 不能是 paymentService,会直接调用兜底方法,没有进行远程调用。
         *
         * 因为@Resource是先通过名称匹配注入,在通过类型。
         */
        @Resource
        private IPaymentService iPaymentService;
    
        @GetMapping("/consumer/openFeign/get/{id}")
        public CommonResult<?> openFeign(@PathVariable String id) {
            return iPaymentService.get(id);
        }
    }
    
    1. service
    // 远程调用接口
    @FeignClient(value = "cloud-nacos-provider-payment", fallback = PaymentService.class)
    public interface IPaymentService {
    
        @GetMapping("/get/{id}")
        CommonResult<?> get(@PathVariable("id") String id);
    }
    
    // 兜底方法
    @Component
    public class PaymentService implements IPaymentService {
    
        @Override
        public CommonResult<?> get(String id) {
            return new CommonResult<>(5555, "openFeign 返回方法", null);
        }
    }
    

11.Sentinel持久化规则

  1. 重启使用Sentinel应用的客户端,sentinel流控规则将消失,生产环境需要将配置规则进行持久化。

  2. Sentinel流控规则可以持久化到Redis、Nacos、file、zk和Consul中。

  3. 本次将Sentinel规则持久化进Nacos中,只要Nacos里面的配置不删除,针对Sentinel Client在Sentinel Server上的配置的流控规则持续有效。

  4. 修改微服务cloud-nacos-sentinel-service8401。

    1. pom.xml添加依赖
    <dependency>
        <groupId>com.alibaba.csp</groupId>
        <artifactId>sentinel-datasource-nacos</artifactId>
    </dependency>
    
    1. 修改yml。
    spring:
      application:
        name: cloud-nacos-sentinel-service
      cloud:
        nacos:
          discovery:
            server-addr: http://127.0.0.1:8848
        sentinel:
          transport:
            #配置Sentinel dashboard地址
            dashboard: http://127.0.0.1:8080
            port: 8719
          # 从Nacos中获取流控规则的配置信息的配置
          datasource:
            ds1:
              nacos:
                server-addr: http://127.0.0.1:8848
                dataId: cloud-nacos-sentinel-service
                groupId: DEFAULT_GROUP
                data-type: json
                rule-type: flow
    
    1. 在Nacos中创建dataId: cloud-nacos-sentinel-servicegroupId: DEFAULT_GROUPdata-type: json的配置信息。
    [{
        "resource": "/byUrl",
        "IimitApp": "default",
        "grade": 1,
        "count": 1, 
        "strategy": 0,
        "controlBehavior": 0,
        "clusterMode": false
    }]
    
    1. 11.3中配置信息的解释。
      1. resource:资源名称。
      2. limitApp:来源应用。
      3. grade:阈值类型,0表示线程数, 1表示QPS。
      4. count:单机阈值。
      5. strategy:流控模式。0:表示直接,1:表示关联,2:表示链路。
      6. controlBehavior:流控效果,0表示快速失败,1表示Warm Up,2表示排队等待。
      7. clusterMode:是否集群。
  5. 待解决问题。需要手动在Nacos中添加流控规则,能不能在Sentinel中创建规则的时候直接同步保存到Nacos中?待完善......

posted @ 2021-10-07 20:08  行稳致远方  阅读(38)  评论(0)    收藏  举报