ThrottlingController、WarmUpController和WarmUpRateLimiterController都是 Sentinel 流量整形(Traffic Shaping)控制器的核心实现 ,它们都实现了 TrafficShapingController 接口,用于决定请求是否可以通过(canPass)。每种控制器代表一种 限流策略/算法,适用于不同场景。
下面我将从 接口定义 → 四种控制器 → 对比总结 → 使用建议 四个层面帮你系统理解。
🧩 一、统一接口:TrafficShapingController
java
public interface TrafficShapingController {
boolean canPass(Node node, int acquireCount, boolean prioritized);
boolean canPass(Node node, int acquireCount);
}
- 作用:判断当前请求是否可以"通过"流量控制。
- 参数 :
node:统计节点(记录 QPS、线程数等)acquireCount:本次请求消耗的"令牌"数量(通常为 1)prioritized:是否优先级请求(可抢占或等待)
✅ 所有流控算法都通过这个接口被调用,实现"策略模式"。
🔢 二、四种控制器详解
1. DefaultController ------ 快速失败(Reject Immediately)
✅ 算法类型:
- 基于阈值的硬限流(类似令牌桶的"立即拒绝"模式)
🔧 核心逻辑:
java
int curCount = (grade == QPS) ? node.passQps() : node.curThreadNum();
if (curCount + acquireCount > count) {
if (prioritized && grade == QPS) {
// 尝试"占用未来令牌"并等待(PriorityWaitException)
}
return false; // 直接拒绝
}
return true;
📌 特点:
- 超过阈值 立刻抛出
FlowException。 - 支持 优先级请求 :可尝试"预占"未来时间窗口的配额,并等待(
PriorityWaitException)。 - 适用于 对延迟敏感、不允许排队 的场景。
💡 典型场景:
- API 网关限流
- 防刷、防攻击
- 微服务间调用保护(避免雪崩)
⚠️ 这是 Sentinel 默认的流控控制器。
2. ThrottlingController ------ 匀速排队(Rate Limiter / Leaky Bucket)
✅ 算法类型:
- 匀速器(Guava RateLimiter 风格)
- 请求按固定速率通过,超出则 排队等待 (最多等
maxQueueingTimeMs)
🔧 核心逻辑:
- 维护一个
latestPassedTime(上次放行时间) - 计算当前请求 期望放行时间 = 上次时间 + 间隔
- 如果等待时间 ≤ 最大排队时间 → 等待后放行;否则拒绝
java
long costTime = (statDurationMs * acquireCount) / count; // 每个请求间隔
long expectedTime = latestPassedTime.get() + costTime;
if (expectedTime - currentTime <= maxQueueingTimeMs) {
sleep(...); return true;
} else {
return false;
}
📌 特点:
- 平滑请求,削峰填谷
- 可能 阻塞线程 (
Thread.sleep) - 精度支持毫秒或纳秒(根据配置自动选择)
💡 典型场景:
- 数据库写入限流(防止打爆 DB)
- 第三方 API 调用(如短信、支付)
- 需要严格控制请求速率的后台任务
🌟 类似 Guava 的
RateLimiter.acquire(),但支持超时拒绝。
3. WarmUpController ------ 预热/冷启动(Warm Up)
✅ 算法类型:
- 动态阈值限流(模仿 Guava 的 warm-up,但基于 Token Bucket 思想)
🔧 核心思想:
- 系统刚启动时处理能力低("冷"),逐渐提升到最大 QPS("热")
- 用 storedTokens(剩余令牌数) 表示系统"热度":
- 令牌多 → 系统冷 → 允许 QPS 低
- 令牌少 → 系统热 → 允许 QPS 高(达到
count)
关键参数:
warningToken:警戒线(开始进入 warm-up 区域)maxToken:最大令牌数(完全冷状态)slope:从冷到热的斜率
📌 特点:
- 防止冷系统被突发流量打垮
- 不排队,只动态调整阈值
- 基于历史 QPS (
passQps) 动态计算
💡 典型场景:
- 应用刚启动(JIT 未优化、连接池未建好)
- 缓存预热期间
- 数据库连接池初始化阶段
📚 灵感来自 Guava,但 Sentinel 用 令牌桶模型 实现,更贴合 QPS 控制。
4. WarmUpRateLimiterController ------ 预热 + 匀速排队
✅ 算法类型:
- WarmUp + Throttling 的结合体
🔧 核心逻辑:
- 先调用
syncToken()更新 warm-up 状态(同WarmUpController) - 再根据当前"有效 QPS"(可能是 warm-up 中的较低值)计算 请求间隔
- 然后像
ThrottlingController一样 排队等待
java
double effectiveQps = (inWarmUp) ? warmingQps : count;
costTime = acquireCount / effectiveQps * 1000;
// 然后排队...
📌 特点:
- 既有 冷启动保护 ,又有 匀速放行
- 请求可能被 延迟处理,但不会因突发流量导致系统崩溃
💡 典型场景:
- 高并发入口服务(如秒杀系统)
- 需要平滑启动 + 平滑处理的混合场景
- 对稳定性要求极高的核心链路
🆚 三、四种控制器对比总结
| 控制器 | 算法类型 | 是否排队 | 是否动态阈值 | 适用场景 |
|---|---|---|---|---|
DefaultController |
快速失败 | ❌ 否 | ❌ 否 | 通用限流、防刷、微服务保护 |
ThrottlingController |
匀速排队 | ✅ 是(可超时) | ❌ 否 | 平滑请求、DB/第三方 API 保护 |
WarmUpController |
冷启动 | ❌ 否 | ✅ 是(从低到高) | 系统启动期、缓存预热 |
WarmUpRateLimiterController |
冷启动 + 匀速 | ✅ 是 | ✅ 是 | 高稳定性要求的核心服务 |
🛠️ 四、如何选择?
| 你的需求 | 推荐控制器 |
|---|---|
| "超过阈值就直接拒绝" | DefaultController |
| "请求要匀速处理,不能突刺" | ThrottlingController |
| "系统刚启动,怕被打挂" | WarmUpController |
| "既要防冷启动,又要匀速处理" | WarmUpRateLimiterController |
💡 在 Sentinel 规则中通过
FlowRule.setControlBehavior(...)设置:
CONTROL_BEHAVIOR_DEFAULT→DefaultControllerCONTROL_BEHAVIOR_RATE_LIMITER→ThrottlingControllerCONTROL_BEHAVIOR_WARM_UP→WarmUpControllerCONTROL_BEHAVIOR_WARM_UP_RATE_LIMITER→WarmUpRateLimiterController
✅ 总结一句话:
Sentinel 的流量整形控制器提供了 从简单拒绝到智能排队+预热 的完整限流能力:
- 快 :
Default------ 超了就拒- 稳 :
Throttling------ 匀速放行- 柔 :
WarmUp------ 冷启保护- 稳+柔 :
WarmUpRateLimiter------ 二者兼得
理解这些控制器,就能根据业务特性 精准选择限流行为 ,在 可用性、稳定性、用户体验 之间取得最佳平衡。