本文介绍 Sentinel(阿里巴巴开源的流量治理框架) 中的核心组件之一:FlowSlot 及其辅助类 FlowRuleChecker。它的作用是在请求进入受保护资源时,根据预设的流控规则(FlowRule)判断是否应该拒绝该请求。
下面我们将从 设计目标、核心机制、关键概念、执行流程、扩展能力 五个维度深入解析。
一、设计目标:做什么?
FlowSlot 的核心职责:实现流量控制(限流)
- 它位于 Sentinel 责任链(Slot Chain)中,在
StatisticSlot之后; - 利用
StatisticSlot收集的实时指标(如 QPS、线程数); - 遍历该资源的所有
FlowRule,一旦有任意一条规则被触发,就抛出FlowException,拒绝请求。
✅ 用户可通过捕获 FlowException 实现降级、兜底逻辑。
二、核心机制:如何限流?
1. 两种限流维度(grade)
FlowRule 的 grade 字段决定限流依据:
| grade 值 | 含义 | 适用场景 |
|---|---|---|
0 (RuleConstant.FLOW_GRADE_THREAD) |
线程数隔离 | 防止慢调用占用过多线程(类似 Hystrix 线程池隔离) |
1 (RuleConstant.FLOW_GRADE_QPS) |
QPS 限流 | 控制每秒请求数,应对突发流量 |
📌 数据来源:
DefaultNode/ClusterNode中由StatisticSlot统计的curThreadNum()和passQps()。
2. 三种流量整形策略(controlBehavior)
当 QPS 超限时,Sentinel 不只是"直接拒绝",还支持更智能的 流量整形(Traffic Shaping):
| 策略 | 常量 | 行为 | 类比算法 |
|---|---|---|---|
| 立即拒绝 | CONTROL_BEHAVIOR_DEFAULT |
超过阈值直接抛异常 | --- |
| 预热(Warm Up) | CONTROL_BEHAVIOR_WARM_UP |
系统冷启动时,逐步提升阈值到设定值 | 梯形/指数增长 |
| 匀速排队(Rate Limiter) | CONTROL_BEHAVIOR_RATE_LIMITER |
以固定速率处理请求,排队等待 | 漏桶(Leaky Bucket) |
✅ 文档中明确指出:匀速排队 = 漏桶算法的实现
→ 这正是你之前提供的 Wikipedia "Leaky Bucket" 内容在 Sentinel 中的实际应用!
三、关键概念解析
1. FlowRule 的组成要素
每个 FlowRule 包含:
resource: 资源名(如/api/order)count: 阈值(如 QPS=100)grade: 限流维度(线程 or QPS)strategy: 关联策略(直连、关联、链路)controlBehavior: 流量整形行为limitApp: 限制来源(如只限制来自 "appA" 的请求)
2. 限流策略(strategy)
| 策略 | 常量 | 说明 |
|---|---|---|
| 直接 | STRATEGY_DIRECT |
默认,直接对当前资源限流 |
| 关联 | STRATEGY_RELATE |
当关联资源(如 /api/pay)达到阈值,限流当前资源(如 /api/order) |
| 链路 | STRATEGY_CHAIN |
只对特定调用链路(Context 名称)限流 |
3. 限流来源(limitApp)
"default":对所有来源生效"other":对未明确指定的来源生效"appA":仅对 origin="appA" 的请求限流(需在ContextUtil.enter(resource, origin)中设置)
四、执行流程详解
FlowSlot.entry() 流程:
java
public void entry(...) throws Throwable {
checkFlow(...); // ← 核心:检查是否触发限流
fireEntry(...); // 继续责任链(如 DegradeSlot)
}
checkFlow() 内部逻辑:
-
获取该资源的所有 FlowRule
javaCollection<FlowRule> rules = FlowRuleManager.getFlowRules(resource); -
逐条检查规则
javafor (FlowRule rule : rules) { if (!canPassCheck(rule, ...)) { throw new FlowException(...); // ← 触发限流! } } -
canPassCheck()决策过程:- 判断是否集群模式(Cluster Mode)→ 调用 Token Server
- 否则走本地限流:
passLocalCheck()- 根据
limitApp+strategy选择正确的统计节点(OriginNode/ClusterNode/ 关联资源节点) - 调用
rule.getRater().canPass(selectedNode, count, prioritized)Rater是具体限流算法的实现(如DefaultController、WarmUpController、RateLimiterController)
- 根据
💡
Rater接口是 策略模式 的体现,不同controlBehavior对应不同Rater。
五、集群限流(Cluster Flow Control)
当 rule.isClusterMode() == true 时:
- 客户端向 Token Server 请求令牌;
- Server 全局协调,确保集群总 QPS 不超阈值;
- 若 Server 不可用:
fallbackToLocalWhenFail=true→ 降级为本地限流;- 否则 → 直接放行(避免雪崩)。
✅ 这是 Sentinel 高可用设计 的体现。
六、与 Leaky Bucket 的关系(重点!)
文档中明确提到:
"This strategy is an implement of Leaky Bucket. It is used to handle the request at a stable rate..."
在 Sentinel 中:
- 匀速排队(Rate Limiter)模式 就是 漏桶算法的实现;
- 它不直接丢弃请求,而是让请求 排队等待,以固定速率(如每 10ms 处理一个)通过;
- 适用于 消息队列消费、定时任务、削峰填谷 等场景;
- 实现类:
RateLimiterController(内部使用AtomicLong记录下次允许通过的时间戳)。
🔍 对比你之前提供的 Wikipedia 内容:
- Leaky Bucket as a Queue:请求进入队列,以固定速率流出 → Sentinel 的匀速排队正是如此!
- 虽然 Sentinel 没用 FIFO 队列,但通过 时间戳+等待 模拟了"排队"效果。
七、总结:FlowSlot 的核心价值
| 能力 | 说明 |
|---|---|
| 多维度限流 | 线程数 / QPS |
| 精细化控制 | 按来源(origin)、按调用链、按关联资源 |
| 智能流量整形 | 预热、匀速排队(漏桶) |
| 集群协同 | 全局限流,避免单机视角偏差 |
| 高可用降级 | 集群失败 → 本地限流 or 放行 |
八、最佳实践建议
- QPS 限流优先于线程数限流(除非有明确慢调用问题);
- 突发流量用匀速排队,避免系统被打垮;
- 冷启动服务配置 WarmUp,防止流量洪峰;
- 关键接口按 origin 限流,实现租户隔离;
- 集群限流用于分布式场景,但需部署 Token Server。
附:Sentinel 限流流程图
[请求进入]
↓
NodeSelectorSlot → ClusterNodeBuilderSlot → StatisticSlot(统计指标)
↓
FlowSlot(检查 FlowRule)
├── QPS 超限? → 抛 FlowException
├── 线程数超限? → 抛 FlowException
└── 通过 → 继续 DegradeSlot(熔断)...
🧠 记住 :
FlowSlot是 决策者 ,StatisticSlot是 数据提供者,二者配合实现精准限流。
通过理解 FlowSlot,你就掌握了 Sentinel 流量控制的灵魂 。而其中的 匀速排队 = 漏桶算法,正是理论(Wikipedia)与实践(Sentinel)的完美结合。