Sentinel组件学习使用
1. Sentinel是什么
Sentinel是阿里巴巴开源的一款面向分布式系统的实时监控和自动化故障恢复工具。它主要用于流量控制、熔断降级和系统负载保护,旨在帮助开发者有效地保护应用程序,防止故障和异常情况的发生。Sentinel不仅支持Java语言,还提供了Go、C++等多语言的原生实现,广泛应用于微服务架构中。
常见的容错解决方案
| 方案名 | 描述 |
|---|---|
| 隔离 | 将系统按照一定的原则划分为若干个服务模块,各个模块之间相对独立,无强依赖。当有故障发生时, 能将问题和影响隔离在某个模块内部,不波及其它模块。常见的隔离方式有:线程池隔离和信号量隔离. |
| 超时 | 在上游服务调用下游服务的时候,设置一个最大响应时间,如果超过这个时间,下游未作出反应,就断 开请求,释放掉线程。 |
| 限流 | 限流就是限制系统的输入和输出流量已达到保护系统的目的。为了保证系统的稳固运行,一旦达到的需要 限制的阈值,就需要限制流量并采取少量措施以完成限制流量的目的。 |
| 熔断 | 在互联网系统中,当下游服务因访问压力过大而响应变慢或失败,上游服务为了保护系统整体的可用性, 可以暂时切断对下游服务的调用。这种牺牲局部,保全整体的措施就叫做熔断。 |
| 降级 | 降级其实就是为服务提供一个托底方案,一旦服务无法正常调用,就使用托底方案。 |
2. Sentinel的作用
Sentinel提供了以下几个核心功能:
- 实时监控:Sentinel可以监控分布式系统中的各种指标,如QPS(每秒查询率)、CPU、内存等,并提供实时的监控数据和报警功能。
- 流量控制:根据系统的负载情况动态调整流量,以保证系统的稳定性和可靠性。
- 熔断降级:当系统负载过高或某个服务出现故障时,Sentinel可以自动熔断降级,减少对整体系统的影响。
- 系统负载保护:通过多种手段保护系统不被过载请求压垮。
- 热点流量防护:对热点参数进行流量控制,防止流量突增导致的系统崩溃。
3. 为啥使用Sentinel
相较于传统的熔断降级工具如Hystrix,Sentinel具有以下优势:
- 更广泛的应用场景:Sentinel不仅适用于Spring Cloud,还适用于Dubbo、gRPC、Servlet等多种应用场景。
- 更丰富的功能:Sentinel除了熔断降级、流量控制外,还提供了系统保护、热点流量防护、授权等多种功能。
- 灵活的规则配置:Sentinel提供了丰富的规则配置功能,支持动态调整,易于管理和维护。
| Sentinel | Hystrix | resilience4j | |
|---|---|---|---|
| 隔离策略 | 线程池隔离/信号量隔离 | 信号量隔离 (并发线程数限流) | 信号量隔离 |
| 熔断降级 | 基于异常比率、响应时间 | 基于异常比率 | 基于异常比率、异常数 |
| 实时统计 | 滑动窗口 (LeapArray) | 滑动窗口 (基于 RxJava) | Ring Bit Buffer |
| 限流 | 基于QPS,支持基于调用关系的限流 | 有限的支持 | Rate Limiter |
| 流量整形 | 支持预热模式、匀速器模式、预热排队 | 简单的 Rate Limiter | 不支持 |
| 系统自适应保护 | 支持 | 不支持 | 不支持 |
| 控制台 | 提供开箱即用的控制台,可配置规则、查看秒级监控、机器发现 | 简单的监控查看 | 不提供控制台,可对接其他监控系统 |
4. 项目整合Sentinel
整合的项目相关版本如下:
| 项目 | 版本 |
|---|---|
| Spring boot | 2.7.18 |
| Spring cloud | 2021.0.9 |
| sentinel dashboard | 1.8.9 |
本项目springCloud 版本:sentinel 控制台版本:
4.1. 搭建Sentinel Dashboard
首先,需要下载Sentinel Dashboard的jar包,并启动Dashboard服务。
sentinel 提供一个轻量级的控制台, 它提供机器发现、单机资源实时监控以及规则管理等功能。
下载控制jar包
https://github.com/alibaba/Sentinel/releases
启动控制台
bash
# 下载Sentinel Dashboard jar包
# 启动Dashboard服务 (这里使用静默启动)
nohup java -Dserver.port=8718 -Dcsp.sentinel.dashboard.server=ip:8718 -Dproject.name=sentinel-dashboard -jar /home/sentinel-dashboard-1.8.9.jar >nohuout &
访问请求
启动后,你可以在浏览器中通过访问 http://localhost:8081(或者你指定的端口)来访问 Sentinel Dashboard。默认的用户名和密码都是 sentinel。

相关功能
| 核心模块 | 功能介绍 |
|---|---|
| 簇点链路 | 支持接口 / 自定义资源监控,新增「链路维度」筛选(比如按调用链路过滤接口) |
| 流控规则 | 保留 QPS / 并发数限流,支持 Warm Up、排队等待、匀速排队等策略,规则配置界面更简洁 |
| 熔断降级 | 支持慢调用、异常比例、异常数熔断,新增「熔断恢复时间」精细化配置 |
| 热点规则 | 支持参数级限流,例外项配置支持多值(比如多个商品 ID 白名单) |
| 授权规则 | 黑白名单支持 IP / 服务名,适配 Spring Cloud 微服务场景 |
| 系统规则 | 支持 CPU、负载、线程数、入口 QPS、响应时间 5 维度限流,保护应用全局稳定性 |
| 实时监控 | 监控数据采样精度提升,支持按实例 / 接口维度导出监控数据 |
| 机器列表 | 展示实例的 JVM、CPU、内存状态,新增「实例离线自动清理」功能 |
4.2. 整合sentinel
在SpringCloud项目中引入Sentinel的依赖,并配置Dashboard地址。
pom.xml
xml
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
application.yml
yaml
spring:
cloud:
sentinel:
enabled: true # 控制整个应用是否接入Sentinel全部能力
eager: true # 热启动,应用启动时立即初始化 Sentinel
filter:
# 启用 Sentinel 内置的 CommonFilter Web 拦截器
# 想要web接口自动生效限流规则,则需要打开
enabled: true # 启用 Sentinel Web 拦截器
# 控制台地址
transport:
#Sentinel dashboard 与该服务进行通信 (服务端通信)
port: 8719
# 配置 Sentinel dashboard 地址 (客户端接口)
dashboard: 127.0.0.1:8718
4.3. 项目中使用
| 使用方式 | 核心说明(简要易懂 + 使用场景 + 优缺点) |
|---|---|
| 硬编码方式 - 手动埋点 | 通过 Sentinel 原生 API(SphU.entry("资源名"))硬编码 ✅ 优点:极致灵活,支持所有复杂业务场景 ✅ 场景:非 Spring 环境、框架定制开发、特殊业务逻辑保护 ⚠️ 缺点:代码侵入严重、耦合度高 |
| 注解式开发 - 精准控制 | 在任意方法(Controller/Service/ 工具类) 上添加注解 @SentinelResource, 手动指定「资源名」+「限流降级兜底方法」。 ✅ 优点:灵活度极高、精准控制到单个方法,支持所有规则(限流 / 熔断 / 热点 / 黑白名单) ✅ 场景:核心业务方法、Service 层核心逻辑、需要精准容错的场景 ⚠️ 缺点:少量代码侵入(仅加注解),几乎无影响。 |
| 动态规则 - 自动适配 | 配置filter.enabled: true,无需修改任何业务代码 , Sentinel 自动拦截所有Controller接口/RequestMapping接口, 默认以「完整请求路径」作为限流资源名 ✅ 优点:零开发成本、接入最快、全局生效 ✅ 场景:所有普通 HTTP 接口的限流 + 熔断 + 系统保护 ⚠️ 缺点:仅支持 web 接口,无法对 Service 层方法做规则控制 |
硬编码形式
核心 API 介绍
java
// 1. 核心入口:定义需要保护的【资源名】,所有规则都绑定这个资源名
SphU.entry("自定义资源名");
// 2. 必须捕获的异常:所有限流/熔断/降级触发时,都会抛出该异常(核心)
com.alibaba.csp.sentinel.slots.block.BlockException
// 3. 可选捕获的异常:细分异常类型(按需使用)
BlockException 子类:
- FlowException:触发限流规则抛出
- DegradeException:触发熔断降级规则抛出
- ParamFlowException:触发热点参数限流抛出
- AuthorityException:触发黑白名单规则抛出
固定用法模块(版本1.7.x 之后)
java
Entry entry = null;
try {
// 1. 标记资源入口:资源名自定义,规则里的resource字段和这个保持一致即可
entry = SphU.entry("自定义资源名");
// 2. 写被保护的业务逻辑:Http层接口逻辑 / Service层业务逻辑
// 比如:查询用户、创建订单、调用第三方接口等
业务逻辑代码...
} catch (BlockException e) {
// 3. 限流/熔断/降级 触发后的【兜底降级逻辑】
// 这里写触发规则后的友好返回,不会抛异常给上层,实现容错
兜底逻辑代码...
} finally {
// 4. 必须执行:释放资源,避免内存泄漏,无论是否异常都要执行
if(Objects.nonNull(entry)){
entry.exit();
}
}
注意: 在sentinel控制台配置对应的资源的熔断、限流、降级等规则
示例代码
java
/**
* 硬编码测试流程
*/
@GetMapping("/list")
public AjaxResult list(SysDept dept) throws BlockException {
Entry entry = null;
try{
entry = SphU.entry("http_get_list_code");
//TODO 模拟业务请求逻辑
Thread.sleep(1000);
}catch (BlockException e){
if(e instanceof FlowException){
log.error("限流了");
return success("限流了");
}
if(e instanceof DegradeException){
log.error("降级了");
return success("降级了");
}
if(e instanceof ParamFlowException){
log.error("参数限流了");
return success("参数限流了");
}
if(e instanceof AuthorityException){
log.error("权限异常了");
return success("权限异常了");
}
if(e instanceof SystemBlockException){
log.error("系统异常了");
return success("系统异常了");
}
return success("服务异常");
} catch (InterruptedException e) {
throw new RuntimeException(e);
} finally {
if(Objects.nonNull(entry)){
entry.exit();
}
}
return success("测试成功");
}
配置限流、熔断规则
注解形式
在需要保护的方法上使用@SentinelResource注解,并指定资源名称和限流、熔断、热点。
java
@SentinelResource(value = "http_get_info", blockHandler = "blockInfoHandler",fallback = "fallbackInfoHandler")
@GetMapping("/info")
public AjaxResult selectConfigList(@RequestParam String userId) {
//TODO 模拟业务请求逻辑
try {
log.info("http_get_info请求资源:{}",userId);
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
return success("测试成功");
}
/**
* 规则:原方法入参 + BlockException e ,返回值和原方法一致
* 触发场景:限流、熔断、热点、关联、链路 任意流控规则命中,都会执行这个方法
*/
public AjaxResult blockInfoHandler(String userId, BlockException e) {
// 1. 打印日志(生产必加,排查是哪种流控规则触发)
log.info("流控规则触发 → http_get_info 被限流/熔断,userId=" + userId + ",异常类型=" + e.getClass().getSimpleName());
// 2. 返回友好的兜底提示(前端能正常展示,不返回500)
return AjaxResult.error("系统繁忙,请稍后重试(请求被限流/熔断保护");
}
/**
* 规则:原方法入参 + Throwable e ,返回值和原方法一致
* 触发场景:原方法抛出任何异常(空指针、业务异常、运行时异常等),都会执行这个方法
*/
public AjaxResult fallbackInfoHandler(String userId, Throwable e) {
// 1. 打印完整异常栈(生产必加,排查业务报错原因)
e.printStackTrace();
// 2. 返回友好的兜底提示,隐藏具体异常信息
return AjaxResult.error("查询信息失败,服务内部异常,请稍后重试");
}
注意blockHandler、fallback的对应的方法 入参、出参 需要和原始方法保持一致,blockHandler需要新增BlockException e入参、blockHandler需要 Throwable e入参
注解上相关参数说明
| 参数名 | 核心作用(极简描述) |
|---|---|
value |
定义资源名称(必填,限流 / 熔断规则绑定此名称) |
blockHandler |
限流 / 熔断触发时的兜底方法(处理 BlockException) |
blockHandlerClass |
指定外部类,存放 blockHandler 静态兜底方法 |
fallback |
业务异常 / 运行时异常的兜底方法(处理 Throwable) |
fallbackClass |
指定外部类,存放 fallback 静态兜底方法 |
defaultFallback |
全局兜底方法,所有未配兜底的资源通用 |
exceptionsToTrace |
指定需要捕获的异常类型 |
exceptionsToIgnore |
指定需要忽略的异常类型(不触发兜底) |
entryType |
资源调用类型(默认 OUT 出站,IN 入站,极少改) |
Filter形式
在配置文件开启filter配置后,sentinel会将所有的http请求接口自动配置成资源(资源名默认是接口请求路径,如/cust/getInfo)
yaml
spring:
cloud:
sentinel:
filter:
# 启用 Sentinel 内置的 CommonFilter Web 拦截器
# 想要web接口自动生效限流规则,则需要打开
enabled: true # 启用 Sentinel Web 拦截器
注意:此处自动扫描后,添加熔断、限流规则后,触发后无任何兜底方法,直接抛BlockException异常,前端返回500错误,用户体验极差,日志混乱,不能直接用于生产。正常生产使用会关闭filter,使用注解@SentinelResource来控制。
配置规则
在上述无论是使用注解、硬编码形式都需要再sentinel配置相关的限流、熔断、热点等规则,满足某种规则条件下才能触发熔断限流。
配置相关规则

以上述限流规则配置单机qps为5,超过5触发限流熔断,效果如下(图1是硬编码形式、图2是注解形式)

