location /ws {
  proxy_read_timeout 180s;
  proxy_send_timeout 180s;
}

连接挂着不动反而没事,客户端每 30 秒发一次心跳,第 61 秒收到 close code 1006,error.log 里是 upstream timed out (110: Connection timed out)。先别急着动参数,把报错原文和时间点记下来,顺序反了容易白折腾。

原因不复杂,proxy_read_timeout 计的是后端向 nginx 回数据的时间,nginx 只看后端有没有写回,客户端发上来的心跳不重置这个计时器。服务端收到心跳只回了空 pong,没往上写业务帧,60 秒一到连接就被掐掉。

这次卡住的地方就在「proxy_read_timeout」这一环,单独把它拎出来验证,别和其他改动混在同一次发布里。备份不是备了就行,恢复一次才算数,很多备份文件打开才发现是空的。

接口问题先分清是没发出去、发出去了没收到,还是收到了处理失败。偶发问题先统计频率,一小时几次和一天一次,查法完全不同。

处理上按这个顺序:让服务端收到心跳后主动回一帧 pong 让 nginx 看到下行有数据;或者把 proxy_read_timeout 调到心跳间隔的三倍比如 180s;proxy_send_timeout 一起检查 别只改一个;改完抓包看 60 秒处还有没有 FIN。

改完只确认一件事:连接挂满十分钟没有 1006 error.log 里不再出现 upstream timed out。

作者 9823189