目录
- 介绍
- 核心功能
- 安装
- 微服务整合Sentinel
- 流控规则
- 熔断规则
- @SentinelResource注解
- 热点规则
- 授权规则
- 规则持久化
- 总结
介绍
Sentinel 是阿里巴巴开源的一款流量控制、熔断降级组件,主要用于保护微服务系统的稳定性。它以流量为切入点,从流量控制、熔断降级、系统负载保护等多个维度提供保障,适用于高并发场景下的服务稳定性需求。
核心功能
- 流量控制
通过控制并发请求数量或速率保护服务稳定性,支持 QPS(每秒查询率)模式和并发线程数模式。提供多种流量控制效果,如直接拒绝、排队等待、预热模式等,可灵活应对突发流量。 - 熔断降级
当下游服务出现异常或响应时间过长时,自动熔断并停止调用,避免故障传播。支持基于慢调用比例、异常比例或异常数的熔断策略,熔断状态可自动或半自动恢复。 - 系统自适应保护
根据系统实时负载(如: CPU 使用率、平均响应时间)自动调整流量控制规则,防止系统过载。 - 热点参数限流
对高频访问的热点参数(如: 用户 ID、商品 ID)单独限流,防止局部热点导致系统崩溃。 - 实时监控和告警
提供秒级实时监控数据,支持单台机器或集群的汇总运行情况查看。
安装
1. 下载
下载地址:Sentinel 下载
2. 启动命令
java -jar sentinel-dashboard-1.8.8.jar
3. 访问Sentinel管理界面
- 访问地址: http://localhost:8080
- 用户名 / 密码: sentinel / sentinel
微服务整合Sentinel
1. cloud-alibaba-sentinel8401 引入依赖
<!-- SpringCloud alibaba sentinel -->
<dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
<!-- nacos-discovery -->
<dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!-- SpringBoot通用依赖模块 -->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!-- lombok -->
<dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional>
</dependency>
<!-- test -->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope>
</dependency>
2. yml配置
server:port: 8401spring:application:name: cloud-sentinel-servicecloud:nacos:discovery:server-addr: localhost:8848 #Nacos服务注册中心地址sentinel:transport:dashboard: localhost:8080 #配置Sentinel dashboard控制台服务地址port: 8719 #默认8719端口,如果被占用会自动从8719开始依次+1扫描,直至找到未被占用的端口
3. 主启动类
@SpringBootApplication
@EnableDiscoveryClient
public class Main8401 {public static void main(String[] args) {SpringApplication.run(Main8401.class, args);}
}
流控规则
1. 流控模式
- 直接: 默认的流控模式,当接口达到限流条件时,直接开启限流。
- 关联: 当关联的资源达到阈值时,就限流自己。例:当A关联的资源B达到阈值,就限流A自己。
- 链路: 来自不太链路的请求访问同一个目标访问时,实施针对性的不同限流措施。例:A访问C,B访问C,针对A请求访问限流,B请求访问不限流。
2. 流控效果
- 快速失败: 直接失败,抛出异常 Blocked by Sentinel (flow limiting)。
- Warm Up: 冷启动或预热,当请求突然增大时,我们希望处理请求的数量是缓步增多,经过预期的时间后,到达系统处理请求的最大值。
- 排队等待: 当某一秒有大量的请求到来,而接下来几秒则处于空闲状态,我们希望系统在接下来的空闲期间逐渐处理这些请求,而不是在第一秒直接拒绝多余的请求。
熔断规则
1. 慢调用比例
选择以慢调用比例作为阈值,需要设置允许的慢调用RT(最大响应时间),请求的响应时间大于该阈值则为慢调用。当单位统计时长内请求数量大于设置的最小请求数量,并且慢调用比例大于阈值,则接下来的熔断时长内请求会自动被熔断。经过熔断时长后,熔断器会进入探测恢复状态(HALF-OPEN状态),如果接下来的一个请求响应时间小于设置的慢调用RT则熔断结束,否则再次被熔断。
- 熔断状态判断依据: 在统计时长内,实际请求数量>设置的最小请求数量,且实际慢调用比例>比例阈值,则进入熔断状态。
- 比例阈值 = 慢调用次数 / 总调用次数
2. 异常比例
当单位统计时长内请求数量大于设置的最小请求数量,并且异常比例大于阈值,则接下来的熔断时长内请求会自动被熔断。经过熔断时长后,熔断器会进入探测恢复状态(HALF-OPEN状态),如果接下来的一个请求成功(没有出现异常)则熔断结束,否则再次被熔断。
3. 异常数
当单位统计时长内异常数量超过阈值后自动进行熔断。经过熔断时长后,熔断器会进入探测恢复状态(HALF-OPEN状态),如果接下来的一个请求成功(没有出现异常)则熔断结束,否则再次被熔断。
@SentinelResource注解
1. 按资源名称+自定义限流返回
cloud-alibaba-sentinel8401:控制类 FlowLimitController
@RestController
public class FlowLimitController {@GetMapping("/testA")@SentinelResource(value = "SentinelResourceByTestA", blockHandler = "handlerBlockHandler")public String testA() {return "按资源名称SentinelResourceByTestA限流...";}public String handlerBlockHandler(BlockException blockException) {return "服务不可用/(T o T)/~~";}
}
Sentinel 按资源名称配置限流规则
测试结果
- 访问 http://localhost:8401/testA 返回:按资源名称SentinelResourceByTestA限流…
- 连续快速访问 http://localhost:8401/testA 触发限流,返回:服务不可用/(T o T)/~~
2. 按资源名称+自定义限流返回+服务降级
cloud-alibaba-sentinel8401:控制类 FlowLimitController
@RestController
public class FlowLimitController {@GetMapping("/testB/{id}")@SentinelResource(value = "SentinelResourceByTestB",blockHandler = "handlerBlockHandler", fallback = "handlerFallback")public String testB(@PathVariable("id") Integer id) {if (id == 0) {throw new RuntimeException("id为0异常");}return "按资源名称SentinelResourceByTestB限流+服务降级...";}public String handlerBlockHandler(@PathVariable("id") Integer id, BlockException blockException) {return "服务不可用/(T o T)/~~";}public String handlerFallback(@PathVariable("id") Integer id, Throwable e) {return "发生异常:" + e.getMessage();}
}
配置限流规则
测试结果
- 访问 http://localhost:8401/testB/123 返回:按资源名称SentinelResourceByTestB限流+服务降级…
- 连续快速访问 http://localhost:8401/testB/123 触发限流,返回:服务不可用/(T o T)/~~
- 访问 http://localhost:8401/testB/0 返回:发生异常:id为0异常
小结
blockHandler主要针对Sentinel配置的限流规则出现的违规情况处理,fallback针对程序异常后JVM抛出的异常服务降级,这两个可以同时存在。
热点规则
1. 普通限流
针对某个热点参数p1配置限流规则,含有参数p1且QPS超过阈值,就会触发限流。
cloud-alibaba-sentinel8401:控制类 FlowLimitController
@RestController
public class FlowLimitController {@GetMapping("/testHotKey")@SentinelResource(value = "testHotKey",blockHandler = "testHotKeyBlockHandler")public String testHotKey(@RequestParam(value = "p1", required = false) String p1,@RequestParam(value = "p2", required = false) String p2) {return "热点testHotKey限流...";}public String testHotKeyBlockHandler(String p1, String p2, BlockException blockException) {return "服务不可用/(T o T)/~~";}
}
配置热点规则
参数索引从0开始,0代表第一个参数,1代表第二个参数,以此类推。
测试结果
- 访问 http://localhost:8401/testHotKey?p1=a 返回:热点testHotKey限流…
- 连续快速访问 http://localhost:8401/testHotKey?p1=a 触发限流,返回:服务不可用/(T o T)/~~
- 访问 http://localhost:8401/testHotKey?p1=a&p2=999 返回:热点testHotKey限流…
- 连续快速访问 http://localhost:8401/testHotKey?p1=a&p2=999 触发限流,返回:服务不可用/(T o T)/~~
- 访问 http://localhost:8401/testHotKey?p2=999 返回:热点testHotKey限流…
- 连续快速访问 http://localhost:8401/testHotKey?p2=999 返回:热点testHotKey限流…
2. 特殊限流
我们期望热点参数p1等于某个特殊值时,普通限流规则就失效了。
热点规则配置参数例外项
参数类型必须是基本数据类型或String类型
测试结果
- 访问 http://localhost:8401/testHotKey?p1=123 返回:热点testHotKey限流…
- 连续快速访问 http://localhost:8401/testHotKey?p1=123 触发限流,返回:服务不可用/(T o T)/~~
- 连续快速访问 http://localhost:8401/testHotKey?p1=zzyy,QPS小于100 返回:热点testHotKey限流…
授权规则
1. cloud-alibaba-sentinel8401:控制类 EmpowerController
@RestController
public class EmpowerController {@GetMapping(value = "/testEmpower")public String testEmpower(){return "testEmpower授权规则...";}
}
2. 自定义请求来源处理器 MyRequestOriginParser 实现 RequestOriginParser 接口
@Component
public class MyRequestOriginParser implements RequestOriginParser {@Overridepublic String parseOrigin(HttpServletRequest httpServletRequest) {return httpServletRequest.getParameter("serverName");}
}
3. 配置授权规则
黑白名单控制:将haha和666加入黑名单,规定当参数serverName等于haha或666时触发限流。
4. 测试结果
- 访问 http://localhost:8401/testEmpower 返回:热点testHotKey限流…
- 访问 http://localhost:8401/testEmpower?serverName=333 返回:热点testHotKey限流…
- 访问 http://localhost:8401/testEmpower?serverName=haha 返回:Blocked by Sentinel (flow limiting)
- 访问 http://localhost:8401/testEmpower?serverName=666 返回:Blocked by Sentinel (flow limiting)
规则持久化
当微服务应用重启后,Sentinel配置的规则就会消失,因此需要将Sentinel配置的规则进行持久化。
1. cloud-alibaba-sentinel8401 引入依赖
<!-- sentinel-datasource-nacos -->
<dependency><groupId>com.alibaba.csp</groupId><artifactId>sentinel-datasource-nacos</artifactId>
</dependency>
2. yml 配置
server:port: 8401spring:application:name: cloud-sentinel-servicecloud:nacos:discovery:server-addr: localhost:8848 #Nacos服务注册中心地址sentinel:transport:dashboard: localhost:8080 #配置Sentinel dashboard控制台服务地址port: 8719 #默认8719端口,如果被占用会自动从8719开始依次+1扫描,直至找到未被占用的端口datasource:ds1:nacos:server-addr: localhost:8848dataId: ${spring.application.name}groupId: DEFAULT_GROUPdata-type: jsonrule-type: flow #流控规则,具体类型参考com.alibaba.cloud.sentinel.datasource.RuleType
3. Nacos新建配置
[{"resource": "/test","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: 是否集群
4. 测试结果
重启微服务 cloud-alibaba-sentinel8401,访问一次(Sentinel是懒加载) http://localhost:8401/test,就能在流控规则中看到Nacos中的配置。
总结
以上主要介绍了 Sentinel 安装、流控规则、熔断规则、热点规则、授权规则、规则持久化的相关知识,想了解更多 Sentinel 知识的小伙伴请参考 Sentinel 官网 和 Spring Cloud Alibaba 官网 进行学习,学习更多 Spring Cloud 实战实用技巧的小伙伴,请关注后期发布的文章,认真看完一定能让你有所收获。