面向 P6-P7+ 工程师 框架训练型 · 长文 约 9,500–11,000 字 信息截止 2026-08

Sentinel 流量防护体系:
限流、熔断与大促实战的规则判断力

限流不是「把流量挡在门外」,而是在下游容量边界内做有序丢弃与降级。 本文以大促打挂下游为入口,建立 Sentinel 1.8.x 限流 / 熔断 / 热点三类规则的配置不变量, 并交付规则分层案例、大促前检查表与防护排障 SOP——大促前把分层、演练和监控联动做扎实,比临时调阈值更能保命。

主线风格:框架训练 + 问题现场 版本假设:Sentinel 1.8.x + Spring Cloud Alibaba 2021.0.5.0 证据等级:官方文档优先,标注推断与生产经验
问题现场 · 复合场景

1双十一零点:限流配了,为什么下游还是被打穿

复合场景 · 综合多家电商大促复盘的典型模式,非指代具体单一事故 TYPICAL SCENARIO

某电商平台在双十一零点开启秒杀。网关层未做入口限流,promotion-service 瞬时 QPS 从日常约 800 飙至约 12000。该服务通过 Dubbo 调用 inventory-service 扣减库存, 后者连接池仅支撑约 2000 QPS。库存服务线程池打满、响应时间从约 30ms 升至数秒; 上游 promotion 大量线程阻塞等待;同时 order-service 写库链路被拖慢, MySQL 连接数触顶,全站下单接口大面积超时。

事后复盘(仍为复合推演)发现三条结构性失误:团队虽在 Sentinel Dashboard 配了单机 QPS 限流, 但未启用集群限流,各实例各自计数导致「总限流阈值 × 实例数」远超下游容量; 熔断规则阈值过宽,慢调用比例约 80% 才触发,雪崩已发生才生效; 秒杀商品 ID 未配热点规则,少数爆款把共享资源打穿。限流「看得见」,防护却「用不上」。

这篇分享要解决三个问题:第一,Sentinel 限流 / 熔断 / 热点三类规则各自的适用边界与配置不变量; 第二,单机限流与集群限流如何与下游真实容量对齐;第三,大促场景下规则如何分层、如何演练、告警如何联动。 风格上约 45% 框架训练(规则决策树与参数边界)、40% 问题现场(大促复合链路)、15% 体系架构(入口—应用—依赖分层)。 本文基于 Sentinel 1.8.x 公开 API 与机制共识撰写,Spring Cloud Alibaba 集成以 spring-cloud-starter-alibaba-sentinel 为准。文中电商秒杀链路为复合场景, 用于串联三类规则与分层方案,不代表单一真实事故全貌。

与网关 WAF、CDN 限流相比,Sentinel 的优势在应用语义:能针对 deductInventory 而非仅 IP 限流,能与 Dubbo 线程模型对齐,能按 skuId 热点细分。 WAF 挡的是恶意流量,Sentinel 挡的是超出容量的合法流量——大促场景两者并存,不可互相替代。 资源名的一致性是架构落地第一关:@SentinelResource("deductInventory")、Gateway 自定义 API 名、 编程式 SphU.entry("deductInventory") 必须字符串完全一致,Dashboard 多一个空格都会导致规则静默失效。

常见误区

「Dashboard 里有限流规则」不等于「防护生效」。资源名不匹配时 StatisticSlot 仍在统计,但 FlowSlot 挂不上规则, passQps 看起来很「健康」。另一个误区是把单机阈值直接当成集群容量:10 台各配 500,实际可通过约 5000—— 若下游只有 3000,就会重现本章现场。第三个误区是未配置 blockHandlerBlockException 直接变成 500,用户感知比「秒杀已抢光」更差。

分享结构:第二章给出 Sentinel 在链路中的位置与 Slot Chain 总览;第三至五章展开限流、熔断、热点; 第六章划定适合 / 不适合边界;第七章交付大促四层防护与检查表;第八章保全排障 SOP; 第九章收束为决策矩阵与相邻知识地图。机制描述属机制共识,场景数字属数量级经验,上线前必须用本服务 workload 复测。

读者若已经在 Dashboard 配过几条流控规则,仍建议通读集群限流与热点两章——真正拉开大促成功率差距的, 往往不是「会不会点 Dashboard」,而是会不会做容量乘法、会不会给爆款单独加更严例外、 以及会不会在演练里验证 Token Server 故障时的降级算术。这些能力无法靠临时调参补上。把检查表与 SOP 当作可审计资产,而不是分享结束后的附录,是架构治理视角下最重要的习惯迁移。下一章先建立概念地图,再分别拆开限流、熔断与热点参数这三类核心规则。

体系总览 · 概念地图

2Sentinel 在微服务链路中的位置:资源、Slot Chain、规则面

从体系架构视角看,Sentinel 位于业务逻辑与外部依赖之间的治理层:对 inbound 请求 (Controller、Gateway Route)做入口防护,对 outbound 调用(Dubbo Reference、Feign Client、RestTemplate)做出站熔断。 它与 Nacos(T11)配合:规则持久化在 Nacos,实例启动后拉取;与 SkyWalking(T14)配合:block 事件可在 Trace 中看到异常 Span。 核心模块包括:sentinel-core(统计与规则引擎)、sentinel-transport(Dashboard 通信)、 sentinel-datasource-extension(Nacos/Redis 等持久化)、 sentinel-cluster-client/server(集群限流)。理解模块边界有助于排障——规则不生效时先查是「规则未加载」还是「资源名不匹配」。

图 1 · Sentinel 在微服务链路中的治理位置
自制示意图
客户端 / CDN WAF · 边缘限流 L1 网关 GatewayFlowRule route / API 分组限流 L2 应用入站 FlowRule · ParamFlow 集群限流 / 热点 SKU blockHandler 友好文案 L3 出站依赖 线程数限流 + 熔断 Dubbo / Feign / DB 横切能力 Nacos 规则持久化 Token Server 集群配额 Metric / Prometheus Slot Chain(单次 SphU.entry) NodeSelector → ClusterBuilder → Statistic → Flow → Degrade → System → … StatisticSlot 累加 pass/block/exception/rt;FlowSlot / DegradeSlot 分别做流控与熔断判定
读图方式:上半部分是流量经手的治理面(L1→L2→L3);中间是规则与令牌、观测横切; 下半部分是单次入口内部的 Slot Chain——Dashboard 上的 passQps / blockQps 都从这条链路上长出来。
来源:Sentinel 官方文档 基本使用 / SphU 与资源; Slot Chain 机制描述见 主要工作原理(Wiki)
已核验事实

Sentinel 以资源(Resource)为统计与管控单元;流控、熔断、热点、系统保护等规则都挂在资源名上。 请求通过 SphU.entry(resource)(或注解 / 适配器埋点)进入处理器链,由各 Slot 依次完成统计与判定。 来源:Sentinel 基本使用文档

Sentinel 采用滑动窗口统计实时指标(常见配置为秒级 Bucket)。当请求进入资源时, StatisticSlot 负责累加 pass / block / exception / rt,FlowSlot 执行流控,DegradeSlot 执行熔断。 理解这条链路后,Dashboard 上的指标才有判读依据——block 为 0 不一定是「流量不大」, 也可能是资源名未匹配导致规则未挂载。待验证推断:部分团队在 Service Mesh 侧用 Envoy rate limit 替代应用内 Sentinel,迁移成本与观测统一性需单独评估,本文仍以 JVM 内 Sentinel 为主。

团队落地时建议先做一次资源名盘点:列出网关路由、Controller、Dubbo Provider / Consumer、 定时 Job 四类入口,逐一标注是否已有 Sentinel 资源、规则类型、持久化 dataId。 盘点结果往往比「我们配过限流」更能暴露空洞——例如运营后台导出任务与 C 端共用同一写资源、 或 Feign 出站只有超时没有熔断。盘点表应进入 Code Review 检查项:新增对外接口必须同步资源名与至少一条防护规则(限流或熔断), 并写明阈值依据(压测容量、连接池大小或 SLA)。没有依据的阈值,等同于没有防护策略,只是把拍脑袋参数写进了配置中心。

观测侧要预先约定「看哪张盘」。最低可行集合是:按资源聚合的 passQps / blockQps、熔断打开次数、 资源 RT 分位、Token Server 可用性。值班同学应能在三分钟内回答:当前是主动 block 还是被动超时、 block 发生在 L1 / L2 / L3 哪一层、是否集中在某个热点参数。答不上来,说明指标标签或 Dashboard 权限还没准备好, 应在大促前而不是零点现场补齐。

核心机制 · 限流

3限流规则:QPS、线程数、流控效果与集群配额

每条流控规则(FlowRule)绑定一个资源,定义阈值类型、流控效果与调用来源等维度。 框架训练视角下,先建立「统计 → 判定 → 处置」三步不变量,再谈具体参数。

3.1 QPS 限流 vs 并发线程数限流

QPS 限流FLOW_GRADE_QPS)统计单位时间内的请求数,适合入口网关、无状态读接口。 并发线程数限流FLOW_GRADE_THREAD)限制同时执行的线程数,适合下游连接池有限、 或单次调用占用线程时间长的写操作、RPC 同步调用链。二者不可互换:QPS 限流无法阻止 「100 QPS 但每个请求阻塞 10 秒」导致的线程耗尽;线程数限流则无法精确控制每秒写入速率。

维度QPS 限流并发线程数限流
统计对象每秒请求计数当前活跃线程数
典型场景API 网关、查询接口写库、同步 RPC、批处理回调
误配风险慢调用堆积仍占线程无法限制突发流量下的总吞吐
搭配建议与熔断规则组合与连接池 max 对齐并留约 20% 余量

3.2 流控效果:直接拒绝、Warm Up、排队等待

ControlBehavior 决定超限后的行为。直接拒绝立即抛 BlockException, 适合大促入口「快失败」。Warm Up在冷启动阶段按斜率逐步放开阈值,避免重启后瞬时打满下游, 需配置 warmUpPeriodSec(通常 10~60 秒)与 coldFactor (冷启动因子,默认 3 表示从阈值约 1/3 开始爬升)。 排队等待让请求匀速通过,超最大等待时间则拒绝,适合削峰填谷但不能用于延迟敏感链路—— 排队本身消耗线程 / 连接。

来源:Sentinel 官方文档 流量控制(QPS / 线程数 / 效果)

3.3 调用来源、关联流控与决策树

limitApp 支持按调用方限流:设为特定 consumer 时仅该来源计入配额; default 表示所有来源。大促中可用于「运营后台对账」与「C 端下单」分池。 关联流控可限制对某 Provider 接口的总并发,而不只在 Provider 侧限流——多个消费方调用同一库存接口时尤其有用。

面对一个新接口,按以下顺序决策(框架训练不变量):

  1. 瓶颈在哪? DB 连接 / 线程池 → 优先线程数限流;CPU / 无状态计算 → QPS 限流。
  2. 实例数会变吗? 弹性伸缩 → 必须集群限流;固定副本且能心算「单机 = 总容量 / N」→ 可暂用单机。
  3. 是否热点倾斜? 是 → 叠加 ParamFlowRule;否 → 仅 FlowRule。
  4. 下游有 SLA 吗? 有 → 配 DegradeRule,maxRt 锚定 SLA。
  5. 被拒绝时用户看到什么? 必须实现 blockHandler,产品文案区分「抢光」与「系统繁忙」。

3.4 单机限流 vs 集群限流

默认 FlowRule 在每个 JVM 实例独立计数。10 台各配 QPS=500,集群实际可过约 5000 QPS。 若下游库存容量约 3000 QPS,必须要么把单机阈值设为 300(依赖实例数稳定),要么启用 集群限流(Token Server 统一发放令牌)。Token Server 需独立高可用部署; 与业务实例混部会在大促流量下争抢 CPU,导致令牌发放延迟。 若暂时无法部署 Token Server,退而求其次:单机阈值 = 集群总配额 / 当前实例数, 并在 HPA 扩缩容钩子中通过 Nacos 重算阈值——适合副本数变化不频的存量系统。

图 2 · 集群限流与下游容量对齐
自制示意图
网关入口 ~10000 QPS promotion 集群限流 全局配额 count ≈ 2800 inventory 容量边界 压测容量 ≈ 3000 QPS · 留余量 实例 A Client 申请令牌 实例 B Client 申请令牌 实例 N Client 申请令牌 Token Server(双节点 HA) FLOW_THRESHOLD_GLOBAL · 统一配额发放
关键点:集群限流的 count 是全集群总配额,必须 ≤ 下游压测容量并留余量; 排查时看聚合指标,而不是单实例 passQps。
来源:Sentinel 官方文档 集群流控
// 集群限流 FlowRule — Sentinel 1.8.x
FlowRule clusterRule = new FlowRule();
clusterRule.setResource("deductInventory");
clusterRule.setGrade(RuleConstant.FLOW_GRADE_QPS);
clusterRule.setCount(2800);  // 全集群总 QPS
clusterRule.setClusterMode(true);
ClusterFlowConfig config = new ClusterFlowConfig();
config.setFlowId(1001L);
config.setThresholdType(ClusterRuleConstant.FLOW_THRESHOLD_GLOBAL);
clusterRule.setClusterConfig(config);
# application.yml — Spring Cloud Alibaba Sentinel 基础接入
spring:
  cloud:
    sentinel:
      transport:
        dashboard: sentinel-dashboard.internal:8080
        port: 8719
      eager: true  # 冷启动即初始化,避免首请求无规则
      datasource:
        flow:
          nacos:
            server-addr: ${nacos.server}
            dataId: ${spring.application.name}-flow-rules
            groupId: SENTINEL_GROUP
            rule-type: flow
生产经验

限流阈值不要直接抄压测峰值:压测往往在理想数据、无旁路流量下进行,大促还有爬虫、对账、运营后台叠加。 建议以下游容量 × 0.7~0.8 作为初始阈值,演练后再微调。 spring.cloud.sentinel.filter.enabled=true 时 Web 入口会自动埋点,但若业务主要走 Dubbo, Controller 层限流形同虚设——规则应下放到真正耗资源的 RPC 资源名上。 Token Server 单独配堆(通常 512MB~1GB 量级足够)与独立监控,避免与业务混部。

关于「单机限流是否永远过时」:并不。固定副本、容量余量大、团队尚未具备 Token Server 运维能力时, 单机限流仍是可接受的过渡态。关键是把总配额公式写进文档,并在扩缩容流程里强制重算。 真正危险的是「以为配了单机限流就等于保护了下游」,却从不做乘法。 弹性伸缩场景下,宁可暂时把阈值配得偏严并接受更高 block,也不要在扩容后悄悄放大总通行量。

Warm Up 与排队等待常被误用。Warm Up 适合「刚扩容 / 刚发布、缓存未热」的冷启动窗口, 不适合大促零点已经跑了数小时的热集群——热集群用 Warm Up 反而会在预热期内人为压低放行量,制造假性容量不足。 排队等待适合可容忍延迟的异步化入口(例如提交任务进队列),不适合同步下单主链路: 排队占用的线程与连接,本身就是下游雪崩的燃料。大促主链路默认直接拒绝,把「等一等」交给前端重试退避或排队页,而不是让服务端线程池替用户排队。

核心机制 · 熔断

4熔断降级:慢调用、异常比例与 fallback 边界

限流是「主动拒绝过量请求」;熔断是「发现下游已不健康,暂时停止调用以免扩大损伤」。 Sentinel 1.8.x 的熔断策略基于统计窗口内的慢调用比例、异常比例或异常数, 状态机在 Closed → Open → Half-Open 间转换。与 Hystrix 相比,Sentinel 熔断更轻量、 与限流 / 热点统一在 Dashboard 管理,且支持细粒度慢调用比例——这是 Spring Cloud Alibaba 体系 推荐用 Sentinel 替代 Hystrix 的主要原因之一(机制共识,非性能 benchmark)。

问题现场视角:当 inventory 响应变慢但 HTTP 仍返回 200(业务码表示库存不足 vs 系统错误混淆)时, 异常比例熔断可能不触发,必须依赖慢调用比例。反之,下游直接抛 Dubbo RpcException 时,异常比例更快生效。 生产上应对同一资源只选一种主策略,避免多条 DegradeRule 叠加令运维难以理解触发原因。

策略触发条件适用场景
慢调用比例RT > maxRt 的请求占比 ≥ 比例阈值下游变慢但未必抛异常,如 DB 锁等待
异常比例异常请求占比 ≥ 比例阈值下游明确返回错误,如 503 / 连接拒绝
异常数窗口内异常次数 ≥ 计数阈值低 QPS 接口,比例统计不稳定

慢调用比例中,maxRt 应设为业务 SLA 的 1.5~2 倍而非平均 RT。 若 P99 约 200ms,maxRt 设 500ms 较合理;设 2000ms 则熔断严重滞后。 比例阈值常见 0.5~0.8,大促核心链路建议偏保守(约 0.5)。 timeWindow 过短会导致 Half-Open 探测过于频繁;过长则恢复慢,建议 10~30 秒并按演练调整。 minRequestAmount 是触发熔断的最低样本量,避免低流量误触发。

图 3 · 熔断器 Closed / Open / Half-Open 状态转换
自制示意图
Closed 正常统计与放行 Open 快速失败 · fallback Half-Open 有限探测流量 慢调用/异常超阈值 timeWindow 到期 探测成功 → Closed 探测失败 → Open
机制共识:Half-Open 阶段通常仅允许有限探测请求;成功则回到 Closed 并清空统计,失败则重新 Open。 timeWindow 是给下游恢复的 breathing room,不是单纯「惩罚时长」。
来源:Sentinel 官方文档 熔断降级
// 慢调用比例熔断 — Sentinel 1.8.x
DegradeRule rule = new DegradeRule("queryProductDetail")
    .setGrade(CircuitBreakerStrategy.SLOW_REQUEST_RATIO.getType())
    .setCount(0.5)
    .setSlowRatioThreshold(0.5)
    .setStatIntervalMs(20000)
    .setMinRequestAmount(10)
    .setTimeWindow(15);
DegradeRuleManager.loadRules(Collections.singletonList(rule));

4.1 blockHandler 与 fallback 的边界

@SentinelResourcefallback 处理业务异常blockHandler 处理限流 / 熔断 blocked。 降级逻辑应无外部依赖:读本地缓存、返回兜底静态数据、引导「活动火爆请稍后再试」, 避免 fallback 内再调 RPC 形成二次雪崩。注意 fallback 默认不捕获 BlockException。 熔断与限流叠加时,先匹配流控再匹配熔断;Open 状态下新请求直接被拒绝,不再消耗下游资源。 系统自适应保护(SystemRule)按本机 load / RT / 线程数降载,不能替代对下游容量的精确限流—— 大促核心链路不建议把 SystemRule 当作唯一手段。

「抖动式熔断」是大促夜常见的次生现象:下游偶发 GC 或短时锁等待把慢调用比例顶过阈值, Open 后短暂恢复,Half-Open 探测又撞上下一次停顿,Grafana 上 degrade 曲线呈锯齿。 此时若只把 timeWindow 调长,会掩盖下游问题并拉长业务不可用窗口; 若只把 maxRt 调宽,则等于放弃熔断。更稳妥的次序是:先确认下游 P99 与 GC / 慢 SQL 是否异常, 再微调熔断参数,同时对非核心出站资源更积极地熔断,把连接池让给下单主链路。 这是「保核心、弃边缘」在熔断层的落地,而不是在限流层一味加阈值。

熔断打开后的用户体验与限流不同:限流常对应「活动太火爆」,熔断更接近「服务暂不可用,请稍后重试」。 产品文案与错误码应区分,便于客服与监控归因。若全局 @ControllerAdvice 与方法级 blockHandler 同时存在,必须约定优先级,避免同一请求返回两套文案或重复打点。

@SentinelResource(
    value = "createOrder",
    blockHandler = "createOrderBlocked",
    fallback = "createOrderFallback"
)
public OrderVO createOrder(OrderRequest req) { /* ... */ }

public OrderVO createOrderBlocked(OrderRequest req, BlockException ex) {
    throw new BizException("ACTIVITY_BUSY", "活动太火爆,请稍后再试");
}

public OrderVO createOrderFallback(OrderRequest req, Throwable t) {
    log.warn("createOrder fallback", t);
    throw new BizException("ORDER_FAILED", "下单失败,请重试");
}
核心机制 · 热点

5热点参数限流:挡住「总量没超、单 key 打穿」

热点规则(ParamFlowRule)针对同一资源下不同参数值做细粒度限流, 解决「总量未超限,但某个热点 key 打穿缓存 / DB」的问题。秒杀场景中,少数 skuId 承担约 80% 流量,全局 QPS 限流无法阻止该 SKU 拖垮库存行锁。 热点维度还常见于:领券活动的 couponId、直播间的 roomId、 恶意刷接口的固定 userId(配合黑名单,而非仅靠 Sentinel)。

5.1 规则要素

  • 参数索引paramIdx):方法第几个参数作为热点维度,从 0 起。
  • 单机阈值count):该参数值在实例上的 QPS 上限。
  • 例外项paramFlowItemList):为特定参数值单独设更严或更宽阈值;爆款通常应更严
  • 统计模式:QPS 或并发线程,与 FlowRule 同理。
ParamFlowRule rule = new ParamFlowRule("seckillDeduct")
    .setParamIdx(0)
    .setCount(100)
    .setGrade(RuleConstant.FLOW_GRADE_QPS);
ParamFlowItem item = new ParamFlowItem().setObject("SKU20261111")
    .setClassType(String.class.getName())
    .setCount(30);
rule.setParamFlowItemList(Collections.singletonList(item));
ParamFlowRuleManager.loadRules(Collections.singletonList(rule));
图 4 · 全局 Flow + 热点 ParamFlow 双层防护
自制示意图
请求到达 L2 全局 FlowRule 集群总配额 ~4500 挡住全站异常尖峰 热点 ParamFlow 默认 skuId ≤ 200 / 实例 爆款例外项 ≤ 30 / 实例 仅该 SKU 被 block 其他 SKU 仍可通行 库存 RPC 线程数 + 熔断
核心价值:某一 skuId 触达热点阈值时,仅该 SKU 被 block,其他 SKU 正常——这是 ParamFlow 相对全局限流的差异点。
来源:Sentinel 官方文档 热点参数限流

5.2 秒杀场景完整配置思路

【复合场景】某秒杀接口 POST /seckill/{skuId},日常 QPS 约 200,大促峰值约 5000。 防护组合:网关 route 限流约 6000 QPS(挡全站异常流量);应用层 seckillOrder 集群限流约 4500 QPS; 热点层 skuId 默认 200 QPS/实例,例外项 Top10 爆款各 50 QPS/实例(或更严如 30); 库存 RPC deductStock 线程数约 60/实例 + 慢调用熔断 maxRt≈300ms。 热点规则需配合参数缓存(内置 LRU),避免参数值空间无限膨胀; PathVariable 场景可能需手动 SphU.entry(resource, EntryType.IN, 1, skuId) 显式传入参数。

常见误区

仅配热点不限全局:攻击者换 SKU 即可绕过;应全局 FlowRule + 热点 ParamFlowRule 双层。 例外项列表手工维护爆款 ID 易遗漏,大促前应结合运营清单批量导入。 另一个误区:把热点阈值设得比全局还高——例外项是用来更严限制爆款,不是给爆款开绿灯。

热点规则与缓存预热、库存分片是同一战场的不同武器。ParamFlow 只能限制「打到这个参数值的请求速率」, 不能替代库存行锁优化或热点 key 本地缓存。若爆款 SKU 在缓存层已经击穿到 DB, 即使热点限流生效,仍应并行推进「本地缓存 + 分桶库存 + 异步扣减」等架构手段。 Sentinel 负责把尖峰变成可预期的拒绝曲线,架构手段负责把拒绝曲线下的真实容量抬高——两者都做,大促才站得住。

参数类型与序列化也值得写进规范:热点维度优先使用 String 或基本类型包装, 避免自定义对象因 equals / hashCode 不一致导致统计失真。Nacos 中 ParamFlow 与 Flow 分 dataId 存放, 避免单文件过大导致推送延迟;值班手册应单独写一页「如何改热点例外项」, 因为大促现场最常见的操作不是改全局限流,而是给新晋爆款补一条更严的例外。

边界判断 · 适合 / 不适合

6什么时候用 Sentinel,什么时候不该硬上

Sentinel 擅长应用语义级流量治理:按资源、按来源、按热点参数做有序丢弃与熔断隔离。 它不是容量本身——block 率长期高位说明该扩容或优化下游,而非永久调高阈值。 也不是安全产品:恶意爬虫、刷单、CC 攻击应在边缘层(CDN / WAF / 网关 IP 规则)优先处理。

适合继续用 Sentinel

  • 微服务入站 / 出站需要与业务资源名对齐的限流熔断
  • 大促、秒杀等合法尖峰,需要与下游容量对齐的配额
  • 热点 SKU / 用户维度倾斜,全局阈值盖不住单 key
  • 已在 Spring Cloud Alibaba 体系,规则希望进 Nacos 与 Dashboard
  • 需要 blockHandler 定制用户体验(业务码而非裸 500)

不适合 / 需换层解决

  • 纯边缘防刷、DDoS——应优先 CDN / WAF / 网关
  • 跨语言、非 JVM 服务为主——考虑网关或 Mesh 统一限流
  • 想用限流「代替」扩容——长期高 block 是容量债
  • 需要精确全局公平性却拒绝部署 Token Server——单机心算会在 HPA 下失真
  • 把 SystemRule 当唯一大促手段——难解释、难对齐业务 QPS
待验证推断

部分团队评估用 Envoy / Istio rate limit 替代应用内 Sentinel,以统一多语言观测。 迁移收益取决于:规则是否仍需业务参数(skuId)、是否已有成熟 Mesh、以及 Dashboard / Nacos 运维 sunk cost。 在 JVM 单体与 SCA 存量为主的团队,应用内 Sentinel 通常仍是成本最低的落地路径——此为架构判断,非官方结论。

还有一类边界需要写清楚:Sentinel 不负责「业务幂等」与「超卖兜底」。 热点限流可以把爆款请求挡在库存服务门外,但挡不住已经通过限流的请求在并发下超卖——那是库存扣减模型与事务设计的问题。 同样,熔断打开后的 fallback 若返回「下单成功」类乐观文案,会制造资损与客诉;降级文案必须偏保守。 把流量防护与业务正确性解耦,评审时分别签字:中间件保证「超容量可预期地失败」,业务保证「放行请求语义正确」。

若团队同时使用网关限流、应用 Sentinel、数据库连接池三道闸,阈值应从下往上反推: 先定 DB / RPC 真实容量,再定应用集群配额,最后定网关入口;自上而下拍脑袋几乎必然在某一层「假防护」。 这与容量规划是同一套算术,只是把结果写进了 FlowRule 与 GatewayFlowRule。

生产实践 · 大促防护

7大促流量防护:四层规则、演练与检查表

大促防护不是 Dashboard 里加几条规则,而是入口 → 应用 → 依赖三层联动、 与容量评估和演练绑定的体系。规则分层决定了「挡在正确位置」还是「挡了个寂寞」。

图 5 · 大促 Sentinel 规则四层分工与监控回路
自制示意图
L1 网关层 全站入口 QPS / IP · GatewayFlowRule · 允许略高于后端以验证后端规则 L2 应用层 核心写接口集群限流 + 热点 ParamFlow · 阈值 = 下游容量 × 0.7~0.8 L3 依赖层 RPC / DB 线程数限流 + 慢调用/异常熔断 · maxRt 与超时对齐 L4 降级层 blockHandler / fallback · 静态页 / 本地缓存 · MQ 异步削峰(补充) 监控回路 pass / block degrade rt P99 TS 健康 Prometheus
读图方式:从上到下是挡流量的顺序;右侧监控横切每一层。 若 L2 block 很少但 L3 熔断频繁,说明 L2 阈值过高或 L3 maxRt 过宽——应回退调整,而非在 L1 盲目加码。

7.1 规则分层验证案例

【复合场景】对第一章双十一链路重做防护:inventory 容量约 3000 QPS,promotion 10 实例。 L1 网关 seckill-route 设约 8000 QPS;L2 deductInventory 集群限流约 2800 QPS(留约 7% 余量); L3 对 InventoryService.dubbo 设线程数约 80/实例(连接池 100);热点 SKU 例外项约 30 QPS/实例。 压测验证:当 L2 触发 block,passQps 稳定在约 2800,inventory RT P99 低于约 500ms; 拔掉 Token Server 模拟故障,应告警并回退单机均分阈值预案。

验证层要点:记录三组数据——(1)无限流基线;(2)仅单机限流;(3)集群限流 + 熔断 + 热点。 网关限流阈值应大于等于后端集群限流之和或略高,否则网关先 block 导致后端规则从未被验证。 Route 级与 API 分组级不要重复计数同一请求——团队应统一只在一层做主限流,另一层做兜底。

// 网关 Nacos gw-flow-rules 示例(resourceMode:1 = API 分组)
[
  {
    "resource": "seckill-api",
    "resourceMode": 1,
    "grade": 1,
    "count": 8000,
    "intervalSec": 1,
    "controlBehavior": 0,
    "burst": 0,
    "maxQueueingTimeoutMs": 500
  }
]

7.2 预案演练与监控联动

大促前至少完成一轮全链路压测 + 故障注入:人为调低阈值观察 block 率与 fallback 展示; 停止某下游实例验证熔断与 Half-Open 恢复;模拟 Nacos 断连验证本地规则缓存是否生效 (应以官方文档与现场验证为准,不应依赖未定义行为)。 必看指标:pass / block QPS、degrade 计数、rt;导出 Prometheus 时按 resource 聚合,勿按实例 IP 无限膨胀。 告警示例:block 率连续数分钟偏高且 pass 贴阈值 → 容量不足或攻击;degrade 突增 → 下游故障; Token Server 连接失败 → 集群限流降级风险。Dashboard 规则变更必须走 Nacos 持久化,禁止仅保存在内存。

组织协同:应用 owner 负责资源命名与 blockHandler;中间件团队维护 Token Server 与 Dashboard; SRE 负责 Prometheus 告警与演练排期。大促前 T-7 完成规则冻结,T-3 仅允许阈值微调, T-0 禁止变更除非故障应急。值班手册应附 Dashboard 只读账号与 Nacos dataId 清单。

# 查看实例 Sentinel 实时指标(默认 8719 端口)
curl -s http://localhost:8719/metric | head -20

# 日志中 BlockException 关键字统计(需开启 block 日志)
grep -c 'BlockException' /var/log/app/application.log

7.3 大促前防护规则自查清单

以下检查表可直接用于大促前巡检。架构治理定位下,检查表比「口头说配过了」更可审计—— 每次大促复盘应对照本表留痕。未通过项阻塞上线。

检查项标准责任人
规则持久化Flow / Degrade / Param 已接入 Nacos(或等价)数据源,非仅 Dashboard 内存应用 owner
集群限流 Token Server核心写链路已启用 clusterMode,Token Server 双节点可用中间件
阈值与容量对齐集群总限流 ≤ 下游压测容量 × 0.7~0.8,文档化依据应用 + SRE
熔断 maxRt慢调用阈值 ≤ SLA P99 × 2,timeWindow 经演练确认应用 owner
热点 SKU 清单运营爆款 ID 已同步至 ParamFlow 例外项或自动导入脚本应用 + 运营
blockHandler / fallback核心资源均已实现,返回码与文案经产品确认应用 owner
网关层限流Gateway Sentinel 路由规则已配置,与后端集群配额一致或略宽网关 owner
监控告警block_qps、degrade、rt 已接入 Prometheus / Grafana 并设告警SRE
压测报告全链路压测含限流触发与熔断恢复场景,报告归档SRE
回滚预案阈值调高 / 关闭规则的配置版本已准备,变更窗口已审批应用 + SRE
资源名审计核心接口资源名与代码 / Dashboard 一致,无孤儿规则或裸奔接口应用 owner
演练记录T-7 压测含 block / 熔断 / fallback 全场景,报告同步值班群SRE
生产经验

大促峰值 block 率「看起来正常」但 DB 仍触顶时,优先查是否有绕过 Sentinel 的写路径 (定时 Job、直连、只限了 HTTP 未限 Dubbo)。资源清单应与代码注解定期 diff。 另一个高频事故:规则只存在 Dashboard 内存,实例重启后防护空洞——CI 应校验 dataId 存在, 启动探针后自动巡检规则条数。

大促前评审可以采用「三组对比表」强制对齐认知:无限流基线、仅单机限流、集群 + 熔断 + 热点。 每一组至少记录:目标 QPS、实际 pass、block 占比、下游 P99、错误率、是否出现连接池打满。 若第三组仍出现下游打满,说明阈值依据错误或存在旁路;若第二组总 pass 仍超容量,说明「乘实例数」问题被复现—— 这正是说服业务方接受集群限流成本的最佳证据。评审结论应形成配置版本 Tag,与网关规则、后端规则同仓管理, 演练环境与生产切换走同一变更流程,避免「演练一套、生产另一套」。

监控告警要分级,而不是「block 就打电话」。建议至少两档: 提示档(block 率升高但 pass 仍健康、用户可感知排队)用于观察; 紧急档(pass 贴阈值且下游 RT / 错误率同步恶化,或 Token Server 不可用)用于叫醒。 把「容量不足」与「防护生效」区分开,才能避免零点把正常防护当成故障去「调高阈值拆防火墙」。

排障 SOP

8流量防护排障 SOP:先分清 block 与 timeout

面向线上「大量 429 / 超时 / 活动不可用」三类现象。进阶排障定位下,SOP 强调 先区分 block 与 timeout:429 或业务码 ACTIVITY_BUSY 多为 Sentinel 主动防护; 长时间挂起后 timeout 多为线程池或连接池耗尽,熔断可能未生效。 勿在未看 metric 前盲目调高阈值——可能是攻击流量本就该被挡。

故障现象排查工具 / 命令根因定位处置方案预防机制
用户大量收到「活动火爆」/ HTTP 429 Dashboard 实时 QPS;curl localhost:8719/metric;Grafana block 率 阈值过低 vs 真实流量超预期 vs 热点 SKU 未单独限流 攻击则维持限流并加网关 IP 规则;容量不足则扩容下游并同步调高集群阈值;热点漏配则补例外项 大促前压测;block 率告警分级;阈值变更走配置中心版本
接口超时增多,但 block 率不高 链路追踪 RT;Dubbo 线程池;sentinel_rt;下游慢查询 熔断未触发(maxRt 过大);线程池耗尽;下游故障未隔离 临时收紧 DegradeRule;对非核心接口手动熔断;扩容或重启僵死实例 核心出站默认配 DegradeRule;线程数限流与连接池对齐
重启后防护失效,流量打穿 启动日志 Sentinel 初始化;Nacos 配置是否拉取成功 eager:false 首请求无规则;规则仅存在 Dashboard 内存;数据源断连 开启 eager;规则迁移 Nacos;重启后脚本校验 metric 中规则相关信号 CI 校验 dataId;启动探针后巡检规则条数
集群限流突然失效,流量倍增 Token Server 健康检查;Client 与 TS 网络;Dashboard 集群状态 Token Server 宕机后 Client 降级为单机限流(机制共识,以 1.8.x 文档为准) 恢复 TS 集群;临时下调单机阈值 = 集群阈值 / 实例数 TS 双活 + 告警;文档化降级算术公式
大促峰值 block 率正常但 DB 仍触顶 对比 Sentinel passQps 与 DB 连接数;查绕过 Sentinel 的写路径(Job / 直连) 限流资源未覆盖全部写入口;只限了 HTTP 未限 Dubbo;读写混部未分离 补挂遗漏资源;对 Job 单独限流或错峰;紧急扩容 DB 只读副本分担读 资源清单与代码注解定期 diff;读写链路分开评审

SOP 使用顺序建议:先看 8719 metric 与 Grafana 确认是否「有 block」; 有 block 则走容量 / 攻击 / 热点三条分支;无 block 却超时则走熔断与线程池分支。 复合告警时(既有 429 又有超时)优先确认是否同一资源:入口被限流而下游仍超时,往往说明还有旁路流量或熔断未覆盖出站。

排障时还有一个易被忽略的时间线技巧:先确认「问题开始时间」是否与规则变更、发布、扩缩容、运营活动开启重合。 许多「限流突然失效」其实是配置推送失败或实例滚动后未拉取到最新 dataId;许多「突然大量 429」其实是运营临时把活动流量切到未挂热点规则的新接口。 把变更时间线与 metric 曲线叠在同一张图上,往往比继续调阈值更快定位。处置完成后,务必把根因写回检查表对应项—— 例如「资源名审计」或「热点 SKU 清单」——否则同一类事故会在下一个大促重复出现。

对值班同学的最低技能要求可以写成四句话:会看 8719 metric;会区分 blockHandler 文案与超时; 会按公式把集群配额拆成单机应急阈值;会在 Nacos 找到 Flow / Degrade / Param 三个 dataId。 四句话过关,再谈调优;四句话不过关,先补 Runbook,而不是在零点现场开「限流原理」培训。

决策框架 · 收尾

9决策矩阵、相邻知识地图与带走清单

9.1 决策矩阵

现场信号 继续当前策略 迁移 / 切换策略 选型式处置(临时)
多实例 + 下游有明确容量上限 集群限流(Token Server) 暂无 TS → 单机阈值 = 总配额 / N 并挂钩 HPA 紧急下调单机阈值止血
慢调用多、异常少 慢调用比例熔断 异常明确增多 → 切异常比例为主 收紧 maxRt / 提高比例敏感度
总量未超但单 SKU 打穿 全局 Flow + ParamFlow 双层 仅热点 → 补全局限流防换 SKU 绕过 运营清单导入例外项
瓶颈是连接池 / 线程占用 线程数限流 + 连接池对齐 误用 QPS → 迁移为 THREAD 档 先降并发上限再查慢 SQL
block 率长期高位 核查是否攻击或爬虫 扩容下游 / 优化链路,勿永久加阈值 临时加阈值仅作缓冲窗口
重启后规则丢失 检查 eager 与数据源 内存规则 → Nacos 持久化 热推规则应急,事后入库

9.2 相邻知识地图

  • T11 Nacos 配置与注册:规则 dataId、分组、推送失败与本地缓存行为。
  • T13 Dubbo 高性能 RPC:超时重试会放大流量——限流阈值需覆盖「重试后的有效 QPS」。
  • T14 SkyWalking 全链路追踪:把 block / 熔断与慢 Span 关联,区分主动防护与被动超时。
  • T17 K8s 生产稳定性:Pod 被 OOMKilled 后规则随实例消失,需探针与配置中心双保险。
阶段性结论

Sentinel 的价值不在「配了多少规则」,而在规则是否与容量、演练、监控、组织流程对齐。 框架训练可迁移:五步决策树、四层防护、block 与 timeout 分拣;现场数字必须用本服务复测。 把检查表贴进大促评审,比再开一次 Dashboard 培训更能减少「限流配了却打穿」。

若把本文压缩成一张值班卡片,正面只留四行: (1)总配额 = 下游容量 × 0.7~0.8,多实例用集群限流或显式均分; (2)慢调用 maxRt 锚定 SLA,不要锚定平均值; (3)热点与全局必须双层,爆款例外项只许更严; (4)先看 block 再谈加阈值,先看变更时间线再谈「神秘失效」。 背面附上 Nacos dataId 清单与 Token Server 应急公式。卡片能在评审会上被业务与 SRE 同时读懂,这篇分享才算落地。

9.3 带走什么

  • 限流选 QPS 还是线程数,取决于瓶颈是「吞吐」还是「并发占用」;多实例必须算集群总配额,优先集群限流。
  • 熔断 maxRt 与比例阈值要在演练中校准,Open 状态的价值是停止无效等待。
  • 热点规则解决 SKU / 用户 ID 倾斜,必须与全局限流双层叠加;例外项对爆款应更严。
  • 大促防护 = 网关 + 应用 + 依赖分层规则 + Nacos 持久化 + 压测演练 + 监控告警。
  • blockHandler / fallback 是用户体验最后一道关,未实现等于把限流做成 500。
  • 排障先分清 block 与 timeout;勿在未看 metric 前盲目加阈值。
  • Sentinel 是防护手段而非容量替代品——block 率长期高位说明该扩容或优化下游。

本篇以复合场景串联限流、熔断、热点与大促四层防护,核心交付是 规则决策树 + 分层验证案例 + 大促检查表 + 排障 SOP + 决策矩阵。 若你只有三十分钟,请优先带走:单机阈值必须乘实例数、集群限流对齐下游容量、 慢调用熔断锚定 SLA、热点与全局双层、以及检查表第十二项「演练记录」。 建议在本地起 Nacos + Sentinel Dashboard + 一个 Spring Boot Demo, 分别触发 Flow、Degrade、ParamFlow 三种 block,观察 8719 metric—— 一次完整动手比阅读十篇文档更能建立「阈值—现象—指标」的条件反射。