连载中 1/20

爆单那天:雪崩是怎么发生的

2026-07-06 · 3515 阅读 · 0 评论 · 0 赞

十点整,流量像开了闸

老王给 503 咖啡馆三周年策划了「半价日」活动,会员群里预热了三天。10 点整活动上线,App 弹窗推送齐发——一分钟内,下单接口的流量冲到平时的四十倍。监控大盘从绿变黄只用了二十秒,从黄变红又用了二十秒,第三分钟,全站 502,连商品详情页都打不开了。用户投诉像雪片,老王给我打电话时系统还在反复重启反复倒下。这本系列就从这条灾难链讲起——雪崩不是一瞬间的意外,是一条有先后顺序的因果链,每一环都能在代码里找到根源。

第一幕:慢——从连接池打满开始

灾难的第一环在数据库。秒杀下单的接口里有一个热点查询:查库存,走的是一张大表的行级更新,平时 RT(响应时间)50 毫秒。流量冲高四十倍后,数据库 CPU 先顶到 100%,查询排队,RT 从 50 毫秒爬到 500 毫秒、再爬到 5 秒。容量是按「平时流量 × 安全余量」规划的,四十倍流量下,每一个环节都在超卖。应用这头,每个请求都要占一个数据库连接,查询从 50 毫秒变成 5 秒,连接的持有时间翻了一百倍——连接池的 50 个连接瞬间被占满,第 51 个请求开始排队等连接,队伍越排越长

第二幕:堆积——线程池的连锁窒息

连接池满了,请求在等连接;等连接的是谁?是 Tomcat 的工作线程。每个 HTTP 请求占一个工作线程,线程在数据库查询上阻塞 5 秒,200 个工作线程在 10 秒内全部阻塞在等连接或等查询上。新请求到达时没有线程接待,进入 Tomcat 的等待队列;队列满了,操作系统层面直接拒绝连接。此时用户看到的现象是:下单接口超时,商品详情接口也超时——它们明明是两个接口、两张表,但它们共享同一个 Tomcat 线程池、同一个数据库连接池,这就是连坐的物理基础

第三幕:连坐——不相关的服务陪葬

更糟的还在后面。订单服务挂了,但用户手机上的 App 不会因此停手:购物车刷不出来会刷新,详情页打不开会重试,失败触发重试,重试变成新的流量,洪峰之上再叠一层洪峰。会员服务调用订单服务查「最近订单」,没有超时设置,默认等到天荒地老——会员服务的线程也全阻塞了。网关后面一排服务,一个倒下,传染一片,这就是雪崩这个词的本义:一块雪松动,整面山坡跟着滑。分布式锁系列第 19 篇的事故五(高频抢锁拖垮注册中心)是这条链的特例,本系列要把整条链系统性拆掉。

第四幕:重启风暴

运维的直觉反应是重启。服务重启要 30 秒,这 30 秒里积压的请求、重试的请求、心急的用户多点几次的请求,全在门外候着——服务刚一起来,积压的流量一齐涌入,刚扩的连接池刚热身就被打满,30 秒后再次倒下。重启一次,倒下一次,系统在死亡边缘反复震荡。老王的半价日最后以「临时下线活动」收场,优惠券没发完,客诉发了一周。

时间现象根因
10:00-10:00:20下单 RT 从 50ms 爬升DB 容量超卖,热点查询排队
10:00:20-10:01连接池满,请求排队RT 拉长导致连接持有时间暴涨
10:01-10:02线程池阻塞,全接口超时共享线程池,无隔离无超时
10:02-10:03不相关服务连坐,全站 502重试风暴 + 无熔断,故障传染
10:03 之后重启后立刻再倒积压流量冲击,无预热无限流

四板斧与一块地基

复盘这条灾难链,每一幕都对应一味药:限流——流量超过容量就果断少接点,宁可得罪十个用户,不能拖垮全站(第 2 到 9 篇);熔断——下游病了就别再问它,快速失败防止线程被拖死(第 10 到 12 篇);降级——接不住的请求给个体面的兜底,而不是裸超时(第 13 篇);隔离——把资源切成舱壁,一舱进水不沉全船(第 14 篇)。这四板斧全都站在同一块地基上:超时——没有超时,任何保护机制都会被「永远等下去」的线程架空(第 15 篇)。下一篇从四板斧的第一把讲起:限流的第一课,固定窗口计数器——最朴素的算法,最经典的突刺。

503

10 年全栈工程师 · 503咖啡馆主理人

#雪崩#过载#连接池#线程池#重试风暴#连坐

评论 (0)

相关推荐

连载中 12/20

排查四件套:jstack、jmap、jstat、jcmd 的实战分工

jstack 看线程在干什么,jmap 看堆里装了什么,jstat 看运行时在变什么,jcmd 是统一入口。四把刀各管一段,配合着用没有查不动的现场。

#jstack#jmap#jstat#jcmd#排查工具
2026-09-16 · 5 阅读 · 0 评论 · 0 赞
连载中 11/20

GC 日志:把回收过程翻译成人话

一行 GC 日志里塞着七种信息:谁触发的、收了哪、停了多久、活了哪些。加上 -Xlog 配置,再加上日志分析工具,GC 不再是只能盯监控曲线的黑盒。

#GC日志#Xlog#日志分析#GC监控#Full GC排查
2026-09-16 · 13 阅读 · 0 评论 · 0 赞
连载中 10/20

ZGC:亚毫秒停顿是怎么炼成的

百 G 大堆停顿不到一毫秒,靠的是把搬家全部挪到并发阶段——着色指针让引用自带状态,读屏障让搬运中的对象依然可访问。代价是吞吐与内存,收益是停顿与堆大小解耦。

#ZGC#着色指针#读屏障#亚毫秒停顿#分代ZGC
2026-09-15 · 8 阅读 · 0 评论 · 0 赞