if (ws.bufferedAmount > 5 * 1024 * 1024) {
  ws.close(1013, 'too slow');
}

监控里 ws_queued 从 200 涨到 10 万,进程内存多了 3GB 一直不释放,对应的是一个 3G 网络的客户端,吞吐只有 2KB/s。先别急着动参数,把报错原文和时间点记下来,顺序反了容易白折腾。

原因不复杂,服务端只管 send,不管对方收得多快,socket 缓冲满了消息就堆在应用层队列。队列没有上限,慢客户端一直挂着,内存只涨不降。

「发送队列积压」改完先别急着全量,挑一台机器放半天,真有问题这段时间就能看出来。动手前把原文件复制一份带时间戳,出问题立刻换回去,比现场分析快得多。

一次只改一处,改完立刻验证,几个改动叠在一起,出问题就说不清是谁导致的。先做最小复现,能稳定跑出来的问题,排查成本会低一个数量级。

处理上按这个顺序:每个连接的队列设上限 比如 200 条或 1MB;超限先丢非关键帧 还超就 close 1013;监控 bufferedAmount 超过 5MB 打点告警;慢客户端单独降频 只推关键状态。

改完只确认一件事:ws_queued 稳定在 1000 以下 内存回到 1.2GB 慢客户端断开后自动重连。

作者 9823189