1双十一零点:限流配了,为什么下游还是被打穿
某电商平台在双十一零点开启秒杀。网关层未做入口限流,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,就会重现本章现场。第三个误区是未配置 blockHandler,
BlockException 直接变成 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(集群限流)。理解模块边界有助于排障——规则不生效时先查是「规则未加载」还是「资源名不匹配」。
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 开始爬升)。
排队等待让请求匀速通过,超最大等待时间则拒绝,适合削峰填谷但不能用于延迟敏感链路——
排队本身消耗线程 / 连接。
3.3 调用来源、关联流控与决策树
limitApp 支持按调用方限流:设为特定 consumer 时仅该来源计入配额;
default 表示所有来源。大促中可用于「运营后台对账」与「C 端下单」分池。
关联流控可限制对某 Provider 接口的总并发,而不只在 Provider 侧限流——多个消费方调用同一库存接口时尤其有用。
面对一个新接口,按以下顺序决策(框架训练不变量):
- 瓶颈在哪? DB 连接 / 线程池 → 优先线程数限流;CPU / 无状态计算 → QPS 限流。
- 实例数会变吗? 弹性伸缩 → 必须集群限流;固定副本且能心算「单机 = 总容量 / N」→ 可暂用单机。
- 是否热点倾斜? 是 → 叠加 ParamFlowRule;否 → 仅 FlowRule。
- 下游有 SLA 吗? 有 → 配 DegradeRule,maxRt 锚定 SLA。
- 被拒绝时用户看到什么? 必须实现 blockHandler,产品文案区分「抢光」与「系统繁忙」。
3.4 单机限流 vs 集群限流
默认 FlowRule 在每个 JVM 实例独立计数。10 台各配 QPS=500,集群实际可过约 5000 QPS。 若下游库存容量约 3000 QPS,必须要么把单机阈值设为 300(依赖实例数稳定),要么启用 集群限流(Token Server 统一发放令牌)。Token Server 需独立高可用部署; 与业务实例混部会在大促流量下争抢 CPU,导致令牌发放延迟。 若暂时无法部署 Token Server,退而求其次:单机阈值 = 集群总配额 / 当前实例数, 并在 HPA 扩缩容钩子中通过 Nacos 重算阈值——适合副本数变化不频的存量系统。
// 集群限流 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 是触发熔断的最低样本量,避免低流量误触发。
// 慢调用比例熔断 — 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 的边界
@SentinelResource 的 fallback 处理业务异常;
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));
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 里加几条规则,而是入口 → 应用 → 依赖三层联动、 与容量评估和演练绑定的体系。规则分层决定了「挡在正确位置」还是「挡了个寂寞」。
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 不可用)用于叫醒。 把「容量不足」与「防护生效」区分开,才能避免零点把正常防护当成故障去「调高阈值拆防火墙」。
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—— 一次完整动手比阅读十篇文档更能建立「阈值—现象—指标」的条件反射。