3. 流量控制基础

流量控制是 Sentinel 最核心的功能之一,其本质是通过对流入系统的请求进行精确计量与干预,防止突发流量冲垮后端服务。本章将系统讲解流量控制的基本概念、两种计量模式(QPS 与线程数)以及三种流量整形效果。

3.1 流量控制概念

流量控制(Flow Control)是指系统根据预设的规则,对进入的请求进行速率限制或资源分配调整,确保系统运行在安全水位以下。Sentinel 的流量控制基于以下三个要素:

  • 资源:被保护的业务方法、接口或代码块,通过 SphU.entry() 定义。
  • 规则:针对资源配置的限流阈值与行为,通过 FlowRule 对象描述。
  • 计量模型:统计流量的方式,包括 QPS(每秒请求数)和线程数两种。
核心原则:流量控制不是拒绝所有超限请求,而是通过不同的限流效果(直接拒绝、Warm Up、排队等待)来平滑流量,保护系统稳定性。
流量控制核心流程 用户请求 计量模型选择 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(直接拒绝)
适用场景:QPS 限流适用于大多数 API 网关、Web 接口、RPC 服务等场景,能够有效控制突发流量对后端服务的冲击。

3.3 线程数限流

线程数限流关注的是资源当前正在处理的并发线程数。当某个资源的并发线程数超过阈值时,后续请求会被直接拒绝。这种模式特别适合保护那些处理时间较长、占用线程资源较多的业务逻辑。

与 QPS 限流的区别:

  • 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));
Warm Up 预热阈值变化曲线 0 count/3 count 0 预热时间 时间 初始阈值为 count/3,在 warmUpPeriodSec 内平滑增长至 count

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 平滑接入流量。