“recv() failed (104: Connection reset by peer)”表明客户端或中间设备主动切断空闲长连接,主因是proxy_read_timeout过长且TCP keepalive未启用或参数不匹配,需结合debug日志与ss、nginx_status交叉验证。

排查 Nginx 长连接超时断开,关键不是看 access_log 里的状态码,而是紧盯 error_log 中与连接生命周期相关的底层信号——它不告诉你“请求失败了”,而是明确指出“连接为什么维持不住”。
重点捕获连接级错误关键词
长连接异常中断往往不报 504 或 502,真实线索藏在 error_log 的 errno 和上下文里:
- recv() failed (104: Connection reset by peer):客户端或中间设备(如防火墙、NAT 网关)主动切断空闲连接。常见于 proxy_read_timeout 设置过长,而 TCP keepalive 未启用或参数不匹配。
- upstream prematurely closed connection:后端提前关闭连接。若高频出现,说明 upstream keepalive 连接池已空,Nginx 被迫频繁新建连接,加剧 worker_connections 压力。
- connect() failed (111: Connection refused) while connecting to upstream:后端拒绝连接。结合 upstream connection is busy 提示,基本可判定 upstream keepalive 池满,复用失效。
- worker_connections are not enough:单个 worker 进程连接数已达上限,新连接被立即拒绝(非超时),长连接无法建立或复用失败的根源之一。
调高日志级别暴露真实路径
默认 error 级别会过滤掉连接建立、keepalive 复用、upstream 选择等关键动作。需临时提升:
- 在对应 server 或 location 块中添加:error_log /var/log/nginx/debug_conn.log info;
- info 级即可看到:http proxy connect(是否每次请求都新建 upstream 连接)、upstream connection reused vs created(复用率是否骤降)、keepalive timeout(是否因 proxy_socket_keepalive 关闭导致坏连接滞留)。
- 若需深挖 TCP 层行为(如 FIN/RST 时机),再启用 debug 级(需 Nginx 编译时含 --with-debug)。
结合运行时状态交叉验证
单看日志易误判。必须同步检查:
- 当前活跃连接数:ss -tnp | grep nginx | wc -l,对比 worker_connections × worker_processes 是否接近上限;
- upstream 连接池使用情况:curl -s http://127.0.0.1/nginx_status(需开启 stub_status)或通过 OpenResty 的 /api/upstream 查看活跃连接数;
- TCP keepalive 系统参数:sysctl net.ipv4.tcp_keepalive_time,确保与 Nginx 的 proxy_socket_keepalive、proxy_read_timeout 协同生效(例如:keepalive_time=600,read_timeout=300,避免中间设备先断)。


















