压测 5000 连接时消息延迟从 80 毫秒涨到 2 秒,心跳也开始超时断开,服务端写队列长度打到 6 万条。日志里能对上时间点,这种反而好排。
所有消息进同一个先进先出队列,广播一次几千条挤在前面,心跳排到队尾,等轮到已经超时。心跳本来就不该和业务抢带宽。这一点先确认清楚,后面就不用反复试。
if (queue.length > MAX_QUEUE) { ws.close(1013, 'backpressure'); }
// 心跳用独立 timer 走协议层 ws.ping()
围绕「心跳优先级」排查时,命令行跑一遍比在面板里点十次有用,面板会替你做掉不少隐式操作。偶发问题先统计频率,一小时几次和一天一次,查法完全不同。
改完顺手把文档补一句,省得下次自己重新推一遍。监控和日志的时间要对上,时区不一致会多绕很大一圈。
处理上按这个顺序:心跳单独走高优先级通道 或者直接在协议层发 ping;写队列按连接设上限 超了就丢业务帧保心跳;广播做批量合并 一秒内的多条合成一帧;监控队列长度 超阈值就告警。
结果对不对很好判断,5000 连接下消息延迟回到 200 毫秒以内 心跳超时次数降到 0。
