sentinel:分布式系统的流量防卫兵:以流量为切入点,从流量控制、熔断降级、系统负载均衡保护等多个维度保护服务的稳定性
sentinel 分为两部分:
- 核心库:不依赖任何框架/库,可以运行在所有的java环境,且对Dubbo/springcloud等框架也有较好支持
- 控制台:基于springboot开发,打包后可以直接运行,不需要额外tomcat等容器
雪崩问题:微服务之间相互调用,因为调用链中的一个服务故障,引起整个链路都无法访问的情况。
限流是对服务的保护,避免因瞬间高并发流量而导致服务故障,进而避免雪崩。是一种预防措施
超时处理、线程隔离、降级熔断是在部分服务故障时,将故障控制在一定范围,避免雪崩。是一种补救措施。
安装使用sentinel:
- 下载控制台 jar 包(github下载), sentinel-dashboard-1.8.1.jar
- 直接在 jar包 cmd 执行 java -jar 即可启动。 例: java -jar sentinel-dashboard-1.8.1.jar
- 直接访问 http://localhost:8080 进入控制台登录页面。 sentinel 默认访问端口是 8080 , 默认用户名和地址都是 sentinel
微服务接入sentinel
- 引依赖 spring-cloud-starter-alibaba-sentinel
- 配置文件
点击查看代码
spring:
cloud:
sentinel:
transport:
dashborad: localhost:8080
簇点链路:微服务的每个接入端点都是一个 簇点链路。与之同行的有 流控、降级、热点、授权,分别可添加该簇点对应的规则(都可添加多个)
流控模式:
- 直接(对当前资源限流):统计当前资源的请求,触发阈值时对当前资源直接限流,也是默认的模式
- 关联(高优先级资源触发阈值,对低优先级资源限流):统计与当前资源相关的另一个资源,触发阈值时,对当前资源限流(当关联资源访问量触发阈值时,会对当前资源限流,以免影响对关联资源的影响)
- 关联模式使用场景:两个有竞争关系的资源,一个优先级较高(更新操作),一个优先级较低(查询操作)。 例如当更新操作来不及时,就应该对查询操作进行限流
- 链路模式中,是对不同来源的两个链路做监控。但是sentinel默认会给进入SpringMVC的所有请求设置同一个root资源,会导致链路模式失效。(设置关闭, ...sentinel.web-context-unify:false)
- 链路(对请求来源限流):统计从指定链路访问到本资源的请求,触发阈值时,对指定链路限流 (即只统计从指定的 入口资源 访问到 本资源 的请求)
流控效果:
- 快速失败(QPS超过阈值时,拒绝新的请求):达到阈值后,新的请求会被立即拒绝并抛出FlowException异常。是默认的处理方式。
- warm up(QPS超过阈值时,拒绝新的请求;QPS阈值是逐渐提升的,可以避免冷启动时高并发导致服务宕机):预热模式,对超出阈值的请求同样是拒绝并抛出异常。但这种模式阈值会动态变化,从一个较小值逐渐增加到最大阈值。
- 排队等待(请求会进入队列,按照阈值允许的时间间隔依次执行请求;如果请求预期等待时长大于
超时时间,直接拒绝):让所有的请求按照先后次序排队执行,两个请求的间隔不能小于指定时长。(当请求超过QPS阈值时,快速失败和warm up 会拒绝新的请求并抛出异常。而排队等待则是让所有请求进入一个队列中,然后按照阈值允许的时间间隔依次执行。后来的请求必须等待前面执行完成,如果请求预期的等待时间超出最大时长,则会被拒绝)
热点参数限流:之前的限流是统计访问某个资源的所有请求,判断是否超过QPS阈值。而热点参数限流是分别统计参数值相同的请求,判断是否超过QPS阈值。
热点参数限流对默认的SpringMVC资源无效,需要利用@SentinelResource注解标记资源,要在该服务接入端点加注解@SentinelResource("hot")
隔离和降级限流是一种预防措施,虽然限流可以尽量避免因高并发而引起的服务故障,但服务还会因为其它原因而故障。而要将这些故障控制在一定范围,避免雪崩,就要靠线程隔离(舱壁模式)和熔断降级手段了
线程隔离之前讲到过:调用者在调用服务提供者时,给每个调用的请求分配独立线程池,出现故障时,最多消耗这个线程池内资源,避免把调用者的所有资源耗尽
熔断降级:是在调用方这边加入断路器,统计对服务提供者的调用,如果调用的失败比例过高,则熔断该业务,不允许访问该服务的提供者了
不管是线程隔离还是熔断降级,都是对客户端(调用方)的保护。需要在调用方 发起远程调用时做线程隔离、或者服务熔断。
而我们的微服务远程调用都是基于Feign来完成的,因此我们需要将Feign与Sentinel整合,在Feign里面实现线程隔离和服务熔断。
FeignClient整合Sentinel
- 配置文件:feign.sentinel.enable: true
- 编写失败降级逻辑。(业务失败后,不能直接报错,而应该返回用户一个友好提示或者默认结果,这个就是失败降级逻辑。)
- 实现FallbackFactory,实现该接口可对远程调用的异常做处理
- 定义类实现FallbackFactory接口并给泛型指明是哪个FeignClient的fallbackFactory
- 按要求重写fallbackFactory<泛型>指定feignClient泛型的 create 方法,返回一个指定泛型的 feignClient。然后可对 指定 feign端点进行异常后的兜底操作。 并在配置文件中注入 spring
- 在feignClient接口的 @FeignClient注解 加属性 fallbackFactory = XXXFallbackFactory.class
- 实现FallbackFactory,实现该接口可对远程调用的异常做处理
熔断降级
- 慢调用:业务的响应时长(RT)大于指定时长的请求认定为慢调用请求。 在指定时间内,如果请求数量超过设定的最小数量,慢调用比例大于设定的阈值,则触发熔断、
- 异常比例、异常数:统计指定时间内的调用,如果调用次数超过指定请求数,并且出现异常的比例达到设定的比例阈值(或超过指定异常数),则触发熔断。