SpringCloud13-Sentinel
SpringCloud13-Sentinel
1.Sentinel
- 从流量控制、熔断降级、系统负载保护等多个维度保护服务的稳定性。
- Spring官网文档地址。https://spring-cloud-alibaba-group.github.io/github-pages/hoxton/en-us/index.html#_spring_cloud_alibaba_sentinel。
- Sentinel官网地址。https://sentinelguard.io/zh-cn/docs/introduction.html。
- GitHub源码地址。https://github.com/alibaba/Sentinel。
2.Sentinel下载、安装和运行。
- Sentinel下载地址。https://github.com/alibaba/Sentinel/releases。
- 运行Sentinel,需要使用 8080端口,所以运行时需要保证 8080不能被占用。运行命令java -jar sentinel-dashboard-1.8.2.jar。
- 访问地址。http://localhost:8080。
3.创建微服务cloud-nacos-sentinel-service8401
- pom.xml。
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
- 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
-
Main和业务类不变。
-
Sentinel采用的懒加载说明,没有访问,在Sentinel中是不会显示的请求的,所以执行一次访问。
4.Sentinel流控规则
- 资源名:唯一名称,默认请求路径。
- 阈值类型/单机阈值:QPS(每秒钟的请求数量)︰当调用该API的QPS达到阈值的时候,进行限流;线程数:当调用该API的线程数达到阈值的时候,进行限流。
- 流控模式。
- 直接:API达到限流条件时,直接限流。
- 关联:当关联的资源达到阈值时,就限流自己。
- 链路:只记录指定链路上的流量(指定资源从入口资源进来的流量,如果达到阈值,就进行限流)【API级别的针对来源】。
- 流控效果。
- 快速失败:直接失败,抛异常。
- Warm up:根据Code Factor(冷加载因子,默认3)的值,从阈值/codeFactor,经过预热时长,才达到设置的QPS阈值。
- 排队等待:匀速排队,让请求以匀速的速度通过,阈值类型必须设置为QPS,否则无效。
5.Sentinel流控规则的具体使用
- 限制QPS阈值类型:QPS;单机阈值:1,即每秒只处理一个请求;流控模式:直接,当前访问的路径达到阈值,直接限流;流控效果:快速失败。
效果:当每秒访问的请求超过1次,返回错误信息Blocked by Sentinel (flow limiting)。
- 限制线程数。阈值类型:线程数;单机阈值:1;流控模式:直接;流控效果:无。
效果:当前请求路径值允许一个线程处理请求,当这个线程正在处理请求时,有其他的请求过来,直接报错。Blocked by Sentinel (flow limiting)
- 关联。阈值类型:QPS;单机阈值:1;流控模式:关联/testB;流控效果:快速失败。
效果:当/testBQPS打到阈值时,每秒超过1次,/testA快速失败,返回Blocked by Sentinel (flow limiting)。
默认流控效果的源码,com.alibaba.csp.sentinel.slots.block.flow.controller.DefaultController
- 预热。阈值类型: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
- 排队等候,匀速通过。阈值类型:QPS;单机阈值:1;流控模式:直接;流控效果:排队等候, 超时时间 20000。
就是有多个请求同时过来,匀速每秒处理一个请求,超时,报错Blocked by Sentinel (flow limiting)。注意:匀速排队模式暂时不支持 QPS > 1000 的场景。
6.Sentinel熔断规则
- 熔断策略:慢调用比例;最大RT:200ms;比例阈值:0.5,熔断时长:5s;最小请求:5;统计时长:1000ms。
配置解释:对/testC配置服务降级策略,1000ms内通过了5个请求,并且5个请求有50%的请求时间高于200ms,则打开断路器,进行服务熔断。5妙后,断路器进入半开状态。放入一个请求,请求时间在200ms内,则关闭断路器,正常提供服务。否则,继续打开断路器,5秒后断路器再次进入半开状态。
- 资源名:/testC;熔断策略:异常比例;比例阈值:0.5,熔断时长:5s,最小请求:5;统计时长:1000ms。
配置解释:1000ms内通过了5个请求,并且5个请求有50%的请求出现异常,则打开断路器,进行服务熔断,5妙后,断路器进入半开状态。放入一个请求,没有出现异常,则关闭断路器,正常提供服务。否则,继续打开断路器,5秒后断路器再次进入半开状态。
- 熔断策略:异常数;异常数:5;熔断时长:5s,最小请求:5;统计时长:1000ms。
配置解释:1000ms内通过了5个请求,并且5个请求有5个请求出现异常,则打开断路器,进行服务熔断,5妙后,断路器进入半开状态。放入一个请求,没有出现异常,则关闭断路器,正常提供服务。否则,继续打开断路器,5秒后断路器再次进入半开状态。
7. @SentinelResource注解
- @SentinelResource(value = "hotkey", blockHandler = "blockHandler", fallback = "fallback")。
- value = "hotkey"解释,在Sentinel控制台配置时,可以使用value的值,需要保证value唯一。
- blockHandler = "blockHandler",出现违反SentinelDashboard配置规则的兜底方法,程序运行异常不会采用这个兜底方法。
- fallback = "fallback",程序运行时异常的兜底方法,违反SentinelDashboard 配置规则不会使用这个兜底方法。
- 自定义全局配置兜底方法。@SentinelResource(value = "customer", blockHandlerClass = CustomerBlockHandler.class, blockHandler = "handle01"),当前方法的限流处理,使用CustomerBlockHandler的handle01方法。
- @SentinelResource(value = "get", fallback = "fallback", exceptionsToIgnore = {IllegalArgumentException.class}),忽略IllegalArgumentException异常信息,即不会对程序抛出的IllegalArgumentException异常调用兜底方法,而是直接返回Error Page。
8.热点key配置规则
- 资源名:hotkey;限流模式:QPS模式;参数索引:0,value = "hotkey",方法的第一个参数。会对每次访问带第一个参数的请求进行统计,如果没有带第一个参数不会进行统计;单机阈值:1;统计窗口时长:1s。
配置解释:1s中带着第一个参数访问的请求,不能超过1次,超过一次返回@SentinelResource中定义的兜底方法。
- 热点key高级配置-参数列外项。热点规则同上;参数例外项:参数类型:java.lang.String;参数值:10;限流阈值:100。
配置解释:1s中带着第一个参数访问的请求超过1次,进行服务降级;但是如果第一个参数的值为10,阈值可以打到100,即参数值为5,一秒钟支持访问100次。
9.Sentinel系统配置规则
- Sentinel系统自适应限流从整体维度对应用入口流量进行控制,结合应用的Load、CPU 使用率、总体平均RT、入口QPS 和并发线程数等几个维度的监控指标,通过自适应的流控策略,让系统的入口流量和系统的负载达到一个平衡,让系统尽可能跑在最大吞吐量的同时保证系统整体的稳定性。
- 系统规则的具体配置。
- Load 自适应(仅对 Linux/Unix-like 机器生效):系统的 load1 作为启发指标,进行自适应系统保护。当系统 load1 超过设定的启发值,且系统当前的并发线程数超过估算的系统容量时才会触发系统保护(BBR 阶段)。系统容量由系统的 maxQps * minRt 估算得出。设定参考值一般是 CPU cores * 2.5。
- CPU usage(1.5.0+ 版本):当系统 CPU 使用率超过阈值即触发系统保护(取值范围 0.0-1.0),比较灵敏。
- 平均 RT:当单台机器上所有入口流量的平均 RT 达到阈值即触发系统保护,单位是毫秒。
- 并发线程数:当单台机器上所有入口流量的并发线程数达到阈值即触发系统保护。
- 入口 QPS:当单台机器上所有入口流量的 QPS 达到阈值即触发系统保护。
10.Sentinel整合OpenFeign进行远程调用
-
创建微服务cloud-nacos-provider-payment9003和cloud-nacos-provider-payment9004,作为生成者。pom.xml、yml、Main和业务类保持不变。
-
创建微服务cloud-nacos-consumer-order84作为消费者,通过OpenFeign+LoadBalance调用9003和9004。
- 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>
- yml
# 开启feign对Sentinel的支持 feign: sentinel: enabled: true
- Main
@EnableFeignClients // 添加Feign的注解 @EnableDiscoveryClient @SpringBootApplication public class CloudNacosConsumerOrder84Main { public static void main(String[] args) { SpringApplication.run(CloudNacosConsumerOrder84Main.class, args); } }
- 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); } }
- 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持久化规则
-
重启使用Sentinel应用的客户端,sentinel流控规则将消失,生产环境需要将配置规则进行持久化。
-
Sentinel流控规则可以持久化到Redis、Nacos、file、zk和Consul中。
-
本次将Sentinel规则持久化进Nacos中,只要Nacos里面的配置不删除,针对Sentinel Client在Sentinel Server上的配置的流控规则持续有效。
-
修改微服务cloud-nacos-sentinel-service8401。
- pom.xml添加依赖
<dependency> <groupId>com.alibaba.csp</groupId> <artifactId>sentinel-datasource-nacos</artifactId> </dependency>
- 修改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
- 在Nacos中创建dataId: cloud-nacos-sentinel-service;groupId: DEFAULT_GROUP;data-type: json的配置信息。
[{ "resource": "/byUrl", "IimitApp": "default", "grade": 1, "count": 1, "strategy": 0, "controlBehavior": 0, "clusterMode": false }]
- 11.3中配置信息的解释。
- resource:资源名称。
- limitApp:来源应用。
- grade:阈值类型,0表示线程数, 1表示QPS。
- count:单机阈值。
- strategy:流控模式。0:表示直接,1:表示关联,2:表示链路。
- controlBehavior:流控效果,0表示快速失败,1表示Warm Up,2表示排队等待。
- clusterMode:是否集群。
-
待解决问题。需要手动在Nacos中添加流控规则,能不能在Sentinel中创建规则的时候直接同步保存到Nacos中?待完善......