凌晨2点,CDN节点切换或网关抖动,3万个在线客户端同时断线,并在同一秒发起WebSocket握手。鉴权、TLS升级和连接队列瞬间压满,旧连接未清理,新连接又集中涌入,形成重连惊群效应:入口被重试流量打垮,业务恢复变慢。若客户端固定间隔重连,短暂抖动会放大成持续洪峰;盲目扩容,只是把峰值复制到更多节点。
如果你正在选机器,或者想先把线路和配置跑通再谈长期方案,可以先看看这几家的线路说明和技术参数:野草云(全球云服务器),先看清带宽线路、流量策略和退款条款,再决定要不要迁。
一、同步重连为何越修越忙
根因不是WebSocket,而是超时与重试节奏同步。网关摘除节点后,所有客户端按相同的心跳超时策略醒来;失败后若固定等待5秒,它们便在每个刻度同时冲击入口。握手还要鉴权和升级协议,单次成本远高于复用长连接,请求数因此先于在线数暴涨。

第一层是WebSocket重连退避:失败后按1秒、2秒、4秒、8秒递增等待并设上限,握手成功才重置。第二层是随机抖动窗口,例如取“基础退避加0~50%随机值”,把批量重试摊成连续小批次,削峰而不降低重连量。同时限制连接重试频率,区分网络错误与鉴权拒绝,避免无效认证被反复放大。
二、如何判断限流与容量是否扛得住
判断惊群不能只看CPU。握手新建速率、失败率、鉴权耗时、连接队列和TLS资源占用,更早暴露风险。按区域、版本和实例分桶后,若每秒曲线像“梳齿”,说明超时或定时器仍然同步。抖动窗口不能过宽;边界应是成功率回升、队列不再增长,而非只追求曲线平滑。

服务端需要第二道闸门:服务端握手限流。可按来源IP、租户、版本或令牌桶限制每秒新建连接数,超阈值时返回可重试状态与Retry-After,并让已认证连接和新握手分级调度。限流不能丢包或断开,否则客户端会立即重试;应明确告知延后时间,让客户端降速。
容量压测要复现“旧连接批量死亡、新连接集中涌入”。脚本统一心跳超时并分批注入断线,逐级提高到预计峰值的1.5倍,观察队列能否清空、消息延迟是否稳定。若扩容后尖峰仍原样出现,先查负载均衡是否让同一节点同时失效、客户端是否共享随机种子;同一种子会让抖动重新同步。排查时可借助ServLlama核对进程资源、连接数与日志时间线,再按秒对齐网关指标。
重连退避:不仅要退,还要抖
客户端恢复连接时,应把失败视为常态。指数退避只能解决固定间隔冲击,仍可能让同一批设备同时醒来,因此要叠加随机抖动窗口:每次等待取“基础间隔的指数增长值+0~50%随机值”,并设置最大等待时间。随机数应按设备生成并跨重试保留,不能每次都从同一点开始。失败类型也要分流:网络切换可立即尝试一次,鉴权失败或参数错误应先刷新凭证并停止盲目重试,服务端限流则遵守 Retry-After;只有暂时性故障才持续进入退避。还应清理重复定时器,并记录重试次数、等待时长和失败原因,以确认WebSocket重连退避确实生效。
握手限流与心跳超时:避免惊群和“假在线”
治理重连惊群效应,客户端退避只是第一道防线,服务端必须在协议升级前执行握手限流。按用户、租户、来源 IP、设备令牌和全局连接数分层使用令牌桶或滑动窗口,超额时返回 Retry-After;同时限制同一身份的有效连接数,重连时先关闭旧会话,避免重复订阅、重复消费和消息扇出。

心跳必须成对设计:客户端周期发送 ping,收到 pong 后更新存活时间,服务端清理长期无 pong 的半开连接。心跳超时策略应综合最近一次成功通信、连接代次和状态判断,阈值须大于一个心跳周期并预留弱网余量;连接代次还能帮助丢弃旧会话晚到的消息。常见坑包括 Jitter 范围过小、退避上限过大、断网后仍持续 ping,以及服务端拒绝握手却不回收旧连接。压测应模拟大批客户端同秒掉线,验证限流、排队、清理与恢复速率,而非只做单客户端连通测试。
结语:一份可执行检查清单
上线前逐项确认:①客户端具备指数退避、随机抖动、最大等待和唯一重连定时器;②失败类型已分流,鉴权错误不会无限重试;③服务端在握手阶段按身份与 IP 限流并返回 Retry-After;④同一身份仅保留有效连接,旧会话能及时回收;⑤客户端 ping、服务端 pong 与超时清理已配对;⑥监控展示在线数、握手拒绝率、重连次数、连接存活时长和惊群峰值;⑦压测覆盖同步掉线、弱网、代理超时、服务端发布和凭证过期。任一项缺失,都可能让普通网络波动演变成重连风暴。


喜欢
顶
难过
囧
围观
无聊





