Sentinel
-
概述
- 服务降级,限流, 熔断
-
安装运行
-
Sentinel 分为两个部分:
-
核心库(Java 客户端)不依赖任何框架/库,能够运行于所有 Java 运行时环境,同时对 Dubbo / Spring Cloud 等框架也有较好的支持。默认端口为8719
-
控制台(Dashboard)基于 Spring Boot 开发,打包后可以直接运行,不需要额外的 Tomcat 等应用容器。默认端口为8080
-
-
下载jar包
-
运行命令
- java -jar 下载到本地: sentinel-dashboard-1.7.1.jar
- 两个组成部分这样子都运行了
-
访问 sentinel 管理页面
- http://127.0.0.1:8080
- 登录账号密码均为: sentinel
-
这个jar包的默认端口为8080
-
可以访问页面.在页面配置(也可以代码实现配置, 不过更推荐页面配置),从而实现服务降级, 限流, 熔断
- sentinel 硬代码模式核心api
- SphU定义资源
Tracer定义统计
ContextUtil定义了上下文
- SphU定义资源
- sentinel 硬代码模式核心api
-
界面
-
-
项目工程
-
POM
<dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency> <!-- Sentinel-nacos --> <dependency> <groupId>com.alibaba.csp</groupId> <artifactId>sentinel-datasource-nacos</artifactId> </dependency> <!-- Sentinel依赖 --> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId> </dependency>
-
YML
spring: cloud: nacos: discovery: # 服务注册中心地址 server-addr: 192.168.1.3:8848 sentinel: enabled: true transport: # 默认8719, 如果被占用了会自动从8719开始一次+1, 直至找到未被占用的端口为止 port: 8719 # sentinel dashboard d地址 dashboard: 192.168.1.3:8080
-
主启动类
@SpringBootApplication @EnableDiscoveryClient public class PaymentNacosApplication { public static void main(String[] args) { SpringApplication.run(PaymentNacosApplication.class); } }
-
流控规则
-
-
资源名: 唯一名称, 默认请求路径
-
针对来源: Sentinel 可以针对调用者进行限流,填写微服务名,默认default (不区分来源)
-
阈值类型/单机阈值:
- QPS (每秒钟的请求数量): 当调用该 api 的QPS 达到阈值的时候进行限流
- 线程数:当调用该 api 的线程数达到阈值的时候,进行限流。指的是服务同一时刻处理的线程数。 和QPS区别, QPS限制是在服务外做限制, 而线程数是服务都已近打到了服务中, 在服务内部做限制
-
流控模式
-
直接: api 达到限流条件时, 直接限流 (默认)
-
关联:当关联的资源达到阈值时, 就限流自己
- 关联资源A调用关联资源B, B出问题, 让A做流控。 适用于B流量大量来自于A的情况
-
链路: 只记录指定链路上的流量(指定资源从入口资源进来的流量,如果到达阈值,进行限流)【APi 级别的针对来源】
-
-
流控效果:
-
直接失败:快速失败,抛出异常 (默认)Blocked by Sentinel (flow limiting) ,
- 源码com.alibaba.csp.sentinel.slots.block.flow.controller.DefaultController
-
Warm Up: 根据codeFactor (冷加载因子,默认3) 的值, 从阈值/codeFactor , 经过预热时常达到设置的 APS 阈值)
-
-
源码
-
com.alibaba.csp.sentinel.slots.block.flow.controller.WarmUpController
-
代码
public WarmUpController(double count, int warmUpPeriodInSec) { construct(count, warmUpPeriodInSec, 3); }
-
-
-
排队等待:匀速排队,让请求以以匀速的速度通过,阈值类型必须设置为 QPS , 否则无效。
-
这种方式主要用于处理间隔性突发的流量,例如消息队列。想象一下这样的场景,在某一秒有大量的
请求到来,而接下来的几秒则处于空闲状态,我们希望系统能够在接下来的空闲期间逐渐处理这些请求, 而不是直接拒绝 -
-
源码
- com.alibaba.csp.sentinel.slots.block.flow.controller.RateLimiterController
-
-
降级规则(服务熔断)
-
当资源被降级后,在接下来的降级是将窗口内,对该资源的调用都自动熔断(默认行为是抛出 DegradeException)
-
-
RT(平均响应时间)
-
当 1s 内持续进入 5 个请求,对应时刻的平均响应时间(秒级)均超过阈值(count,以 ms 为单位),那么在接下的时间窗口(DegradeRule 中的 timeWindow,以 s 为单位)之内,对这个方法的调用都会自动地熔断(抛出 DegradeException)。注意 Sentinel 默认统计的 RT 上限是 4900 ms,超出此阈值的都会算作 4900 ms,若需要变更此上限可以通过启动配置项 -Dcsp.sentinel.statistic.max.rt=xxx 来配置。
-
-
代码
@SneakyThrows @GetMapping("/testD") public String testD() { TimeUnit.SECONDS.sleep(1); return "----- testB"; }
-
热点key 限流
-
对包含特定请求参数的请求做限流
-
只适用于QPS模式
-
-
系统规则
-
系统保护规则是应用整体维度的,而不是资源维度的,并且仅对入口流量生效。入口流量指的是进入应用的流量(EntryType.IN),比如 Web 服务或 Dubbo 服务端接收的请求,都属于入口流量
-
从单台机器的 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 达到阈值即触发系统保护。
-
-
系统规则一般不用, 让整个系统都限流是不太友好的
@SentineResource
-
作用:对资源限制、熔断等规则提示做定制化
-
不支持private 方法
-
属性:
- value: 资源名
- blockHandlerClass: 规则处理类
- blockHandler: 规则处理方法
- fallback: 异常处理方法
- defaultFallback: 默认异常处理方法
- blockHandler 和 fallback 的区别
- blockHandler 用来处理Sentinel 限流/熔断等规则达成;
fallback 用来处理接口中业务代码所有异常
- blockHandler 用来处理Sentinel 限流/熔断等规则达成;
- blockHandler 和 fallback 的区别
-
demo
-
// @SentinelResource 的value就是配置的资源名(一般和路径一致就行), blockHandler, 就是处理规则满足后的方法, 注意, 这个blockHandler只处理规则, 不处理其他异常, 其他异常用fallback @GetMapping("/testHotKey") @SentinelResource(value = "testHotKey",blockHandler = "deal_testHotKey") public String testHotKey(@RequestParam(value = "p1",required = false) String p1, @RequestParam(value = "p2",required = false) String p2) { // int age = 10/0; return "------testHotKey"; } public String deal_testHotKey (String p1, String p2, BlockException exception) { return "------deal_testHotKey,o(╥﹏╥)o"; //sentinel系统默认的提示:Blocked by Sentinel (flow limiting) }
-
sentinel规则持久化
-
每次重复服务, 发现sentinel的该服务流控规则没了. 所以要做持久化
-
可以用nacos做持久化.
-
步骤
-
POM
-
<!--SpringCloud ailibaba sentinel-datasource-nacos 后续做持久化用到--> <dependency> <groupId>com.alibaba.csp</groupId> <artifactId>sentinel-datasource-nacos</artifactId> </dependency>
-
YML
-
添加Nacos 数据源配置
-
port: 8401 spring: application: name: cloudalibaba-sentinel-service cloud: nacos: discovery: server-addr: localhost:8848 #Nacos服务注册中心地址 sentinel: transport: dashboard: localhost:8080 #配置Sentinel dashboard地址 port: 8719 #sentinel持久化 datasource: ds1: nacos: # nacos 地址 server-addr: localhost:8848 # 先在nacos 中配置对应的dataId, groupId, data-type dataId: cloudalibaba-sentinel-service groupId: DEFAULT_GROUP data-type: json # flow 对应流控规则 rule-type: flow
-
先在nacos 中配置对应的dataId, groupId, data-type以及json内容。 比如对资源/rateLimit/byUrl的流控规则如下
-
那么对应的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表示Warm up , 2表示排队
clusterMode: 是否集群。 -
自动持久化见如下
-
-
-