Sentinel 详解:流量治理
Sentinel 是阿里巴巴开源的流量治理组件,以"流量"为切入点,提供流量控制、熔断降级、系统负载保护等多维度保护能力。它是 Spring Cloud Alibaba 生态中替代 Hystrix 的核心组件。
一、Sentinel 全景能力
┌─────────────────────────────────────────────────────────────────┐
│ Sentinel 流量治理体系 │
│ │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ 流量控制 │ │ 熔断降级 │ │ 系统保护 │ │
│ │ │ │ │ │ │ │
│ │ • QPS 限流 │ │ • 慢调用比例 │ │ • Load 保护 │ │
│ │ • 并发线程数 │ │ • 异常比例 │ │ • CPU 保护 │ │
│ │ • 关联资源 │ │ • 异常数 │ │ • RT 保护 │ │
│ │ • 链路限流 │ │ • 熔断时长 │ │ • 入口 QPS │ │
│ │ • 热点参数 │ │ │ │ │ │
│ └──────────────┘ └──────────────┘ └──────────────┘ │
│ │
│ ┌──────────────────────────────────────────────────────────┐ │
│ │ Sentinel 控制台 │ │
│ │ • 实时监控:QPS、RT、线程数、通过/拒绝请求数 │ │
│ │ • 规则管理:可视化管理限流/熔断/热点规则 │ │
│ │ • 动态生效:修改规则实时生效,无需重启 │ │
│ └──────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────┘二、流量控制(限流)
2.1 限流模式
| 模式 | 说明 | 场景 |
|---|---|---|
| 直接 | 限制当前资源的 QPS | 限制下单接口每秒 100 次 |
| 关联 | 关联资源达到阈值时,限制当前资源 | 写接口 QPS 过高时,限制读接口 |
| 链路 | 只限制从特定入口进来的请求 | 限制来自秒杀入口的请求,不限制普通入口 |
2.2 限流效果
| 效果 | 说明 |
|---|---|
| 快速失败 | 直接拒绝,抛出 FlowException |
| Warm Up | 预热,初始阈值低,逐渐增加到设定值(防止冷启动被打垮) |
| 排队等待 | 请求排队,匀速通过(类似漏桶算法) |
2.3 代码示例
java
@RestController
public class OrderController {
@GetMapping("/order/create")
@SentinelResource(
value = "createOrder",
blockHandler = "createOrderBlockHandler" // 限流后的降级方法
)
public Result<String> createOrder() {
// 业务逻辑
return Result.success("下单成功");
}
// 降级方法:必须与原方法参数一致,额外加 BlockException
public Result<String> createOrderBlockHandler(BlockException e) {
return Result.fail("系统繁忙,请稍后重试");
}
}三、熔断降级
3.1 熔断策略
| 策略 | 说明 | 触发条件示例 |
|---|---|---|
| 慢调用比例 | 慢调用(RT > 阈值)比例超过设定值 | 1s 内 5 个请求,其中 3 个 RT > 200ms(60%) |
| 异常比例 | 异常比例超过设定值 | 1s 内异常比例 > 50% |
| 异常数 | 异常数超过设定值 | 1 分钟内异常数 > 10 |
3.2 熔断器状态机
┌──────────┐
│ CLOSED │ ← 正常状态,请求正常通过
│ (关闭) │
└─────┬────┘
│ 失败次数达到阈值
▼
┌──────────┐
│ OPEN │ ← 熔断状态,所有请求直接失败
│ (打开) │
└─────┬────┘
│ 经过熔断时长
▼
┌──────────┐
│HALF_OPEN │ ← 半开状态,放行一个探测请求
│ (半开) │
└─────┬────┘
│ 成功 → CLOSED 失败 → OPEN
▼3.3 配置示例
yaml
spring:
cloud:
sentinel:
transport:
dashboard: 127.0.0.1:8080 # Sentinel 控制台地址
port: 8719 # 与控制台通信的端口
datasource:
ds1:
nacos:
server-addr: 127.0.0.1:8848
data-id: order-service-sentinel
group-id: DEFAULT_GROUP
data-type: json
rule-type: flow # 规则持久化到 Nacos四、热点参数限流
对于"秒杀商品详情"这种场景,需要对热门商品单独限流:
java
@GetMapping("/product/{id}")
@SentinelResource(
value = "productDetail",
blockHandler = "productDetailBlockHandler"
)
public Product getProduct(@PathVariable Long id) {
return productService.getById(id);
}规则配置:对参数 id 进行限流,QPS=100,但 id=888 的热门商品只允许 QPS=10。
五、Sentinel vs Hystrix
| 维度 | Sentinel | Hystrix |
|---|---|---|
| 隔离策略 | 信号量隔离 | 线程池隔离 / 信号量隔离 |
| 熔断策略 | 慢调用比例 / 异常比例 / 异常数 | 异常比例 |
| 流量控制 | 丰富(QPS/线程/关联/链路/热点) | 无(仅熔断,不限流) |
| 实时监控 | 控制台可视化 | Dashboard + Turbine |
| 规则动态修改 | 支持,实时生效 | 有限支持 |
| 维护状态 | 活跃维护 | 停止维护 |
| 开源社区 | 阿里,活跃 | Netflix,停维 |
六、生产最佳实践
- 规则持久化:将规则存储在 Nacos,重启后不丢失
- 降级兜底:熔断触发后,必须有合理的降级逻辑(返回缓存、默认值、提示信息)
- 分层限流:Gateway 层全局限流 + Sentinel 服务层精细限流,两道防线
- 监控告警:Sentinel 控制台 + Prometheus 告警,熔断发生时及时通知
- 压测验证:上线前通过压测确定合理的限流阈值,不要拍脑袋设定