nginx代理websocket出现消息延迟或卡顿,根本原因是其默认按短连接逻辑处理长连接,需透传upgrade和connection头、禁用proxy_buffering与proxy_cache、设proxy_read_timeout和proxy_send_timeout为86400、启用tcp_nodelay并关闭tcp_nopush,同时调优系统级并发参数。

WebSocket 经 Nginx 代理后出现消息延迟或卡顿,通常不是网络带宽问题,而是 Nginx 默认按短连接逻辑处理长连接所致。优化核心在于让 Nginx “真正理解” WebSocket 的生命周期,并消除缓冲、超时、协议降级等干扰环节。
确保协议升级完整透传
这是握手成功的前提,缺一不可:
- 必须启用 HTTP/1.1:proxy_http_version 1.1;
- 透传 Upgrade 头:proxy_set_header Upgrade $http_upgrade;(注意变量写法,不能写死为 "websocket")
- 透传 Connection 头:proxy_set_header Connection "upgrade";(引号不能省,也不能设为空字符串)
- 避免缓存干扰:proxy_cache off;,防止 Upgrade 请求被缓存返回 200 而非 101
关闭缓冲并延长连接保活时间
默认缓冲和短超时是消息“卡住”或连接“静默断开”的主因:
- 禁用响应缓冲:proxy_buffering off;——否则小消息会积压在 Nginx 缓冲区,等填满才下发
- 大幅延长读超时:proxy_read_timeout 86400;(24 小时),匹配 WebSocket 长连接特性
- 同步设置发送超时:proxy_send_timeout 86400;,避免大消息分片途中被中断
- 配合后端每 30 秒发一次 ping 帧,确保空闲连接不被误判为失效
启用 tcp_nodelay 降低小包延迟
专治 Nagle 算法导致的毫秒级攒包延迟,对心跳、行情更新、控制指令类小数据(几十~几百字节)效果显著:
- 在 WebSocket 路径块中添加:tcp_nodelay on;
- 同时关闭 tcp_nopush:tcp_nopush off;(避免零拷贝机制延迟小包发出)
- 该配置仅对已成功升级的长连接生效,需以 proxy_set_header Upgrade/Connection 正确配置为前提
- 验证方式:用 ss -i 查看连接,输出含 nodelay 标志即生效
系统与运行时协同调优
单靠 Nginx 配置无法突破底层瓶颈:
- 扩容文件描述符:/etc/security/limits.conf 中为 Nginx 用户设置 soft/hard nofile ≥ 1048576
- 调优内核参数:net.core.somaxconn、net.ipv4.tcp_tw_reuse、net.ipv4.ip_local_port_range
- Nginx 主配置中启用高并发支持:worker_rlimit_nofile 1048576; + events { worker_connections 65535; }
- 后端改用异步运行时(如 Swoole、Uvicorn + async handler),避免阻塞事件循环











