“connection reset by peer”在websocket中途出现,主因是nginx代理未透传upgrade头、后端处理阻塞或客户端消费能力不足;需配置proxy_http_version 1.1及动态connection头,排查tcp零窗口、连接池耗尽及服务异常重启。

“Connection reset by peer” 在 WebSocket 连接中途出现,基本不是网络抖动导致的偶发问题,而是服务端或代理层主动 RST 了连接——常见于 Nginx 代理配置缺失、后端处理阻塞、客户端消费能力不足这三类根因。
Nginx 代理未透传 Upgrade 头导致 101 升级失败
WebSocket 建立依赖 HTTP/1.1 的 Upgrade 协议切换机制,而 Nginx 默认不转发 hop-by-hop 类请求头(如 Connection 和 Upgrade),导致后端收不到升级信号,直接返回普通 HTTP 响应或静默断连。
- 必须显式添加:
proxy_http_version 1.1;、proxy_set_header Upgrade $http_upgrade;、proxy_set_header Connection "upgrade"; - 不要写死
Connection: upgrade—— 应用map指令动态判断,避免非 WebSocket 请求被错误升级:map $http_upgrade $connection_upgrade { default upgrade; '' close; }然后用$connection_upgrade替代硬编码值 - 如果后端是 Java Spring Boot + Tomcat,默认支持 WebSocket,但若启用了
server.tomcat.max-connections限流且值过小,也会在升级阶段触发 RST,需同步检查
客户端接收慢引发 TCP 零窗口与服务端 RST
现象是连接建立成功、心跳正常,但一发业务消息就断,Nginx 日志报 send() failed (104: Connection reset by peer) while proxying upgraded connection。抓包会看到大量 TCP ZeroWindow 包,说明客户端接收缓冲区已满,服务端继续推送时内核直接发 RST。
WebSocket 8.18.2 是该协议规范的一个重要迭代版本,主要优化了连接稳定性与数据传输效率。它通过全双工通信机制,允许客户端与服务器在单一长连接上实时交换数据,大幅降低传统 HTTP 轮询的开销。该版本增强了心跳保活、自动重连及二进制帧传输能力,适用于即时通讯、在线游戏及金融行情推送等低延迟场景,为开发者提供更可靠的实时网络交互基础。
- 典型场景:前端用
ws.onmessage同步执行耗时操作(如解析大 JSON、渲染 DOM),阻塞事件循环,无法及时调用ws.send()或处理后续帧 - 后端(如 Python
websockets库)默认启用ping_interval,但若客户端长期不响应 ping,服务端可能主动断连;建议客户端实现onping并立即回复 pong - 临时缓解可调大 TCP 接收窗口(
net.ipv4.tcp_rmem),但治标不治本;根本解法是客户端加队列+异步消费,或服务端启用背压(如websockets的max_queue参数限制未确认帧数)
后端服务异常重启或连接池耗尽
“Connection reset by peer” 出现在通信中段(非握手阶段),且复现规律为“第二次重连后稳定,一发数据即断”,大概率是后端进程崩溃重启、或连接池满导致新请求被拒绝后 RST 旧连接。
- 检查后端日志是否有
OOMKilled、Segmentation fault或线程 dump;Java 服务重点关注 GC 频繁或java.lang.OutOfMemoryError: unable to create new native thread - 若使用连接池(如 Go 的
http.Transport、Node.js 的agent),确认maxSockets/MaxIdleConns设置合理,避免 WebSocket 连接被误回收 - 注意:某些旧版 libuv 或 OpenSSL 动态库存在 WebSocket 协议栈 bug,更新系统
libssl、libnghttp2后可解决(2024 年多起案例证实)
真正难定位的是“客户端处理慢 → TCP 零窗口 → 服务端 RST”这个链路,它不报错、不丢日志、只在 Nginx error log 里留下一句模糊的 Connection reset by peer。务必用 tcpdump -i any port 80 or port 443 -w ws.pcap 抓包验证是否存在连续的 zero window 包——这是最直接的证据。










