发版重启后 8 台网关在 2 秒内各收到 1000 多条握手,CPU 冲到 100%,握手 backlog 排到 3000,健康检查超时,剩下的机器也被摘掉。日志里能对上时间点,这种反而好排。

客户端重连写的是固定 1 秒后重试,服务恢复的瞬间所有连接同时回来,握手开销集中在一个时间窗。机器一慢握手更慢,客户端等不到就再重试,正反馈把集群压垮。这一点先确认清楚,后面就不用反复试。

const base = Math.min(30000, 1000 * 2 ** retry);
const delay = base / 2 + Math.random() * base / 2;
setTimeout(connect, delay);

「重连风暴」排查到最后往往是很小的一处差异,前面那些复杂猜测可以先放一放。线上出问题先对时间点,跟发布、备份、任务执行的时刻排一排,能省掉一半功夫。

处理上按这个顺序:重连间隔改成指数退避 1 2 4 8 秒并加随机抖动 抖动取间隔的一半;服务端握手阶段限速 按 IP 或连接数排队 超出回 503;发版先摘流量再重启 让客户端自然迁移;加全局重连次数上限 超过就提示用户刷新。

结果对不对很好判断,重启后 30 秒内握手峰值从 8000 降到 1500 左右 健康检查不再超时。

作者 9823189