连载中 14/16

高可用与降级:发号服务挂了怎么办

2026-06-12 · 1773 阅读 · 0 评论 · 0 赞

压测演成的事故

大促前两周,老王组织全链路压测,第一轮就翻车:模拟发号服务实例宕机,预期是流量切到存活实例、下游无感,实际是下单链路整体报错——发号 SDK 的重试没有超时上限,连接池被拖死,错误像瘟疫一样传遍调用方。复盘会上 DBA 说得扎心:号段、雪花、基因都做了,唯独没人问过「发号这一环挂了,业务怎么活」。这一篇补上这门课。

先看清单点在哪

发号链路上有三个可能死的点,逐个加固:

服务实例:发号服务多实例部署、前面挂负载均衡。雪花模式天然无状态,实例随便加——workerID 分配好就行(第 8 篇);号段模式的实例也无需同步,各领各的号段。这一层的冗余最便宜,必须做满。

存储层:号段库挂了才是真麻烦——所有实例的 buffer 迟早耗尽。DB 主从半同步打底,预算足的上多机房;Redis 发号(第 9 篇)同理,哨兵或集群模式起步。雪花模式没有这一层,这也是它高可用的先天优势。

客户端缓冲:其实第 4 篇的双 buffer 就是第一道降级——本地囤着千号,DB 抖三秒下游无感。压测翻车后老王把 SDK 改了:号段取不到时先用尽本地存量再报错,并把重试超时从「无限等」改成「快速失败 + 退避」。

降级阶梯:一级一级往下走

高可用的核心思想不是「不挂」,而是挂了之后每一层都有下一步

第一级:DB 抖动——本地双 buffer 顶住,秒级到分钟级无感。监控 buffer 水位,水位过低告警。

第二级:DB 长时间不可用——号段耗尽在即,切备库或第三机房号段库(号段表的 max 值在备库是延续的,切换后新号段不重叠;这里再度呼应第 3 篇的半同步——异步复制的备库切换会号段回跳,对账逻辑要备好)。

第三级:发号服务整体失联——启用本地兜底发号:业务应用内置一套精简雪花(或预置备用号段),应急开关打开后本地发号。兜底 ID 必须能和正常 ID 区分——比如用时间戳高位的一个保留位做标记,或者落到独立号段区间。为什么必须区分?兜底期间发的 ID 在有序性、安全性上都是降级品,事后要能圈出来做对账与补录。

降级的每一级都要提前想好「什么时候降、谁来拍板、怎么升回来」,写成操作手册。最忌讳的是临时找方案——凌晨三点没人有心情读你的架构文档。

大促专项:容量与预热

大促流量是平时的几十倍,发号侧两个动作:一是容量预估——按峰值 QPS 倒推号段长度,把 step 提前调大(Leaf 的动态 step 会自己适应,但预留量要人工审一遍);二是预热——应用发布或扩容后,新实例的 buffer 是空的,第一波流量全打到 DB,大促前把所有实例的 buffer 预填充,别让新节点在开局就当短板。

监控四件套

指标看什么异常信号
号段消耗速率业务增速与突发流量速率陡增,号段即将提前耗尽
buffer 水位本地存号还能撑多久水位低于安全线,预加载失败
时钟偏移雪花集群 NTP 状态偏移超阈值,回拨风险预警
发号延迟 P99下游体验P99 飙升,DB 或网络异常前兆

最后一条纪律:降级预案必须定期演练。老王把「杀发号实例」「断号段库」「全服失联」三档场景进了季度演练排期,每次演练记录切换耗时与业务影响。预案写在文档里是作文,演练进排期表才是能力。

小结

高可用一句话:实例冗余解决机器挂,双 buffer 解决存储抖,降级阶梯解决整体瘫,兜底 ID 打标可追溯,演练进排期才算数。至此发号器的工程闭环全部搭完:从原理到选型到安全到分片到容灾。但还有一批坑散落在边边角角——位数分配的算术题、时间戳的过期倒计时、号段长度的心理战。下一篇把踩坑实录一次清算。

503

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

#分布式ID#高可用#降级#容灾#大促预案

评论 (0)

相关推荐

连载中 12/20

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

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

#jstack#jmap#jstat#jcmd#排查工具
2026-09-16 · 4 阅读 · 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 赞