文档
前言
想象一个秒杀场景:每秒 10 万请求涌入,任何一个下游服务的"慢"都可能像多米诺骨牌一样拖垮整个系统。Sentinel 就是在这个时刻保护你的"电路开关"。
第一章:理解流量治理的三个层次
1.1 限流(Rate Limiting)
"老子只能处理这么多,多的请排队或滚蛋"
场景:你的服务设计 QPS 是 1000
突然来了 5000 QPS
→ 限流拦截 4000,放行 1000
→ 保证服务不崩溃
1.2 熔断降级(Circuit Breaking)
"下游已经不行了,我先不调了,直接返回 fallback"
场景:支付服务调用库存服务
库存服务响应时间从 50ms → 5000ms
→ 熔断器打开 → 快速失败
→ 支付服务线程池不会被打满
→ 10s 后半开探测 → 恢复则关闭
1.3 系统自适应保护
"系统 Load 已经很高了,拒绝新请求,保护当前处理中的"
不是按 QPS 限流,而是按系统指标:
- CPU 使用率 > 80%
- 系统 Load > 阈值
- RT > 阈值
→ 自动拒绝入口流量
第二章:Sentinel 核心概念
2.1 资源(Resource)
资源是 Sentinel 的保护对象。任何想要保护的代码块都可以是一个资源:
// 方式1:注解(推荐)
@SentinelResource("myResource")
public String doSomething() { ... }
// 方式2:API(代码中埋点)
try (Entry entry = SphU.entry("myResource")) {
// 被保护的代码
} catch (BlockException e) {
// 被限流后的处理
}
2.2 规则(Rule)
每条规则定义了"如何保护资源":
规则类型:
├── FlowRule(流控规则)—— QPS/并发线程数
├── DegradeRule(熔断降级)—— 慢调用/异常比例/异常数
├── SystemRule(系统规则)—— CPU/Load/RT/QPS
├── AuthorityRule(授权规则)—— 黑白名单
└── ParamFlowRule(热点规则)—— 针对特定参数
2.3 Slot Chain(责任链)
Sentinel 内部通过责任链模式处理请求:
请求 → NodeSelectorSlot → ClusterBuilderSlot → StatisticSlot
→ AuthoritySlot → SystemSlot → FlowSlot → DegradeSlot
→ 业务方法
第三章:限流算法详解
3.1 滑动窗口
Sentinel 默认使用滑动窗口算法做统计:
时间轴:[0--1--2--3--4--5--6--7--8--9--10] 秒
窗口大小:1 秒
滑动步长:200ms(5 个桶)
每个桶统计:通过 / 阻塞 / 异常 / RT
效果:1 秒维度精确 QPS 控制
3.2 四种流控效果
| 效果 | 行为 | 适用场景 |
|---|---|---|
| 直接拒绝 | 超出 QPS 立即抛异常 | 一般 API 保护 |
| Warm Up | 阈值从低到高逐渐提升 | 冷启动保护(连接池预热) |
| 匀速排队 | 请求排队,恒定间隔通过 | 消息队列削峰 |
| Warm Up + 排队 | 预热 + 排队混合 | 突发流量 + 冷启动 |
3.3 三种流控模式
// 直接模式:针对当前资源
FlowRule rule = new FlowRule("resourceName")
.setCount(10)
.setGrade(RuleConstant.FLOW_GRADE_QPS);
// 关联模式:关联资源触发时限制自己
// 例如:写操作 QPS 大时限制读操作
rule.setStrategy(RuleConstant.STRATEGY_RELATE);
rule.setRefResource("writeResource");
// 链路模式:只限制入口链路
rule.setStrategy(RuleConstant.STRATEGY_CHAIN);
rule.setRefResource("entryPointA");
第四章:熔断降级深入
4.1 熔断器状态机
┌──────────┐
│ CLOSED │ (正常)
└─────┬────┘
│ 失败达到阈值
┌─────┴────┐
│ OPEN │ (熔断)
└─────┬────┘
│ 休眠时间到
┌─────┴────────┐
│ HALF-OPEN │ (探测)
└──────┬───────┘
成功 ↓ ↑ 失败
CLOSED OPEN
4.2 三种熔断策略
// 慢调用比例
new DegradeRule("resource")
.setGrade(RuleConstant.DEGRADE_GRADE_RT)
.setCount(500) // RT > 500ms 算慢调用
.setTimeWindow(10) // 熔断时长 10s
.setMinRequestAmount(5)
.setSlowRatioThreshold(0.5); // 50% 慢调用触发
// 异常比例
new DegradeRule("resource")
.setGrade(RuleConstant.DEGRADE_GRADE_EXCEPTION_RATIO)
.setCount(0.5); // 异常比例 > 50% 触发
// 异常数
new DegradeRule("resource")
.setGrade(RuleConstant.DEGRADE_GRADE_EXCEPTION_COUNT)
.setCount(20); // 1 分钟内 > 20 个异常触发
第五章:Sentinel vs Hystrix vs Resilience4j
| 特性 | Sentinel | Hystrix | Resilience4j |
|---|---|---|---|
| 状态 | ✅ 活跃维护 | ❌ 停止维护 | ✅ 活跃 |
| 限流 | ✅ 丰富 | ❌ 只有信号量 | ✅ RateLimiter |
| 熔断 | ✅ | ✅ | ✅ |
| Dashboard | ✅ 强大 | ✅ 基础 | ❌ 无内置 |
| 热点限流 | ✅ | ❌ | ❌ |
| 系统保护 | ✅ | ❌ | ❌ |
| 规则动态下发 | ✅ | ❌ | ❌ |
| Spring 集成 | Spring Cloud Alibaba | Spring Cloud Netflix | 独立 |
思考题
- Sentinel 的滑动窗口和常见的固定窗口、令牌桶有什么区别?各有什么优劣?
- 熔断器的「半开」状态为什么要只放行少量请求?如果放行大量请求会怎样?
- 热点参数限流和普通 QPS 限流的底层实现有什么不同?
- 如果 Sentinel Dashboard 挂了,规则还会生效吗?服务会怎样?
下一步
- 学习 Sentinel + Gateway 实现网关层限流
- 学习 Sentinel 集群流控
- 学习 Sentinel + Nacos 规则持久化