3. 流量控制基础
流量控制是 Sentinel 最核心的功能之一,其本质是通过对流入系统的请求进行精确计量与干预,防止突发流量冲垮后端服务。本章将系统讲解流量控制的基本概念、两种计量模式(QPS 与线程数)以及三种流量整形效果。
3.1 流量控制概念
流量控制(Flow Control)是指系统根据预设的规则,对进入的请求进行速率限制或资源分配调整,确保系统运行在安全水位以下。Sentinel 的流量控制基于以下三个要素:
- 资源:被保护的业务方法、接口或代码块,通过
SphU.entry()定义。 - 规则:针对资源配置的限流阈值与行为,通过
FlowRule对象描述。 - 计量模型:统计流量的方式,包括 QPS(每秒请求数)和线程数两种。
3.2 QPS 限流
QPS(Queries Per Second)限流是最常用的流量控制方式,它统计每秒内对某个资源的请求数量,当统计值超过预设阈值时触发限流。Sentinel 采用滑动窗口算法进行精确统计,窗口精度为 500ms。
| 参数 | 说明 | 默认值 |
|---|---|---|
grade |
限流维度,0 表示线程数,1 表示 QPS |
1(QPS) |
count |
QPS 阈值,即每秒允许的最大请求数 | — |
controlBehavior |
限流效果,0 直接拒绝,1 Warm Up,2 排队等待 |
0(直接拒绝) |
3.3 线程数限流
线程数限流关注的是资源当前正在处理的并发线程数。当某个资源的并发线程数超过阈值时,后续请求会被直接拒绝。这种模式特别适合保护那些处理时间较长、占用线程资源较多的业务逻辑。
与 QPS 限流的区别:
- QPS 限流:控制请求的速率,适合短平快的请求。
- 线程数限流:控制请求的并发度,适合耗时较长的请求(如文件上传、复杂计算)。
3.4 限流效果
Sentinel 提供了三种限流效果,分别适用于不同的流量整形需求。下表对比了三种效果的差异:
| 效果 | 控制行为值 | 行为描述 | 适用场景 |
|---|---|---|---|
| 直接拒绝 | 0 |
超过阈值后立即拒绝请求,抛出 FlowException |
对延迟敏感、必须丢弃超限请求的场景 |
| Warm Up | 1 |
系统冷启动时逐步提升阈值,从 count / coldFactor 缓慢增长到 count |
系统刚启动、缓存预热、数据库连接池初始化等场景 |
| 排队等待 | 2 |
请求进入队列匀速通过,超时未获取到令牌则拒绝 | 削峰填谷、消息消费、批量任务处理等场景 |
3.4.1 直接拒绝
直接拒绝是最简单的限流效果。当 QPS 或线程数超过阈值时,Sentinel 立即返回 FlowException,不会对请求做任何缓冲。配置示例:
FlowRule rule = new FlowRule();
rule.setResource("orderService");
rule.setGrade(RuleConstant.FLOW_GRADE_QPS);
rule.setCount(100); // 每秒最多 100 个请求
rule.setControlBehavior(RuleConstant.CONTROL_BEHAVIOR_DEFAULT); // 直接拒绝
FlowRuleManager.loadRules(Collections.singletonList(rule));
3.4.2 Warm Up(预热)
Warm Up 模式用于解决系统冷启动时的流量冲击问题。系统启动时,实际阈值从 count / coldFactor 开始,随着时间推移逐渐增长到配置的 count 值。默认冷启动因子 coldFactor 为 3。
关键参数:
warmUpPeriodSec:预热时长,默认 10 秒。coldFactor:冷启动因子,默认 3,即初始阈值为配置阈值的 1/3。
FlowRule rule = new FlowRule();
rule.setResource("userService");
rule.setGrade(RuleConstant.FLOW_GRADE_QPS);
rule.setCount(300);
rule.setControlBehavior(RuleConstant.CONTROL_BEHAVIOR_WARM_UP);
rule.setWarmUpPeriodSec(20); // 预热 20 秒
FlowRuleManager.loadRules(Collections.singletonList(rule));
3.4.3 排队等待
排队等待效果通过令牌桶算法实现匀速排队。请求到达时,如果当前 QPS 超过阈值,请求不会立即被拒绝,而是进入队列等待,以固定的速率(即配置的 QPS 阈值)被处理。如果等待时间超过 maxQueueingTimeMs,则请求被拒绝。
关键参数:
maxQueueingTimeMs:最大排队等待时间,默认 500ms。
FlowRule rule = new FlowRule();
rule.setResource("paymentService");
rule.setGrade(RuleConstant.FLOW_GRADE_QPS);
rule.setCount(50);
rule.setControlBehavior(RuleConstant.CONTROL_BEHAVIOR_RATE_LIMITER);
rule.setMaxQueueingTimeMs(1000); // 最大排队 1 秒
FlowRuleManager.loadRules(Collections.singletonList(rule));
3.5 三种效果对比总结
| 对比维度 | 直接拒绝 | Warm Up | 排队等待 |
|---|---|---|---|
| 请求成功率 | 低(超限即失败) | 中(预热期后稳定) | 高(排队等待处理) |
| 响应延迟 | 低(立即拒绝) | 低(拒绝或通过) | 中(可能等待) |
| 系统资源消耗 | 低 | 低 | 中(需要队列存储) |
| 适用流量特征 | 平稳流量 | 冷启动流量 | 突发流量 |
| 配置复杂度 | 简单 | 中等(需设置预热时长) | 中等(需设置超时时间) |
在实际生产环境中,通常需要根据业务特点组合使用不同的限流效果。例如,核心交易接口使用排队等待保证成功率,非核心查询接口使用直接拒绝快速失败,新发布的服务使用 Warm Up 平滑接入流量。