nginx 稳定支撑大规模弹幕 websocket 需打通协议升级、连接维持、系统承载三层链路:必须透传 upgrade 和 connection 头,关闭缓冲与缓存,调大读写超时,并协同后端及内核参数优化。

要让 Nginx 稳定支撑大规模弹幕系统的 WebSocket 长连接,核心不是堆参数,而是打通“协议升级—连接维持—系统承载”三层链路。配置错一个关键头或漏调一项系统限制,就可能在万级并发时出现握手失败、随机断连或消息延迟。
必须透传的 WebSocket 升级头
弹幕连接始于 HTTP 握手,Nginx 若未显式转发 Upgrade 和 Connection 头,后端永远收不到升级请求,返回 200 而非 101,前端直接报错“Error during WebSocket handshake”:
- 一定要写 proxy_http_version 1.1 —— HTTP/1.0 不支持 Upgrade,强制升到 1.1 是前提
-
proxy_set_header Upgrade $http_upgrade —— 使用内置变量,原样透传客户端发来的
Upgrade: websocket -
proxy_set_header Connection "upgrade" —— 注意是固定字符串
"upgrade",不是$http_connection;Connection 是逐跳头,不能继承
关闭所有干扰长连接的默认行为
弹幕是持续双向流,Nginx 默认的缓冲、缓存和短超时策略会主动破坏连接:
- proxy_buffering off —— 否则帧被暂存,造成粘包或秒级延迟
- proxy_cache off(或不配任何 proxy_cache_*)—— WebSocket 响应不可缓存,启用即失败
- proxy_read_timeout 86400 —— 设为 24 小时,避免空闲弹幕连接被 Nginx 主动踢出(默认仅 60 秒)
- proxy_send_timeout 86400 —— 保障后端心跳或批量弹幕能完整发出,不因偶发延迟中断
后端与系统级协同调优
Nginx 配置只是入口,真正扛住高并发需前后端+OS 共同配合:
- 后端服务(如 Node.js ws、Go Gorilla、Java Spring WebFlux)必须监听相同路径(如
/danmaku),并信任X-Forwarded-For和X-Forwarded-Proto - 在 Nginx 的
events块中启用高效模型:use epoll;(Linux)、worker_connections 65535;,并匹配系统 ulimit(如nofile 1048576) - 内核参数调优:
net.ipv4.tcp_tw_reuse = 1、net.ipv4.ip_local_port_range = 1024 65535,缓解大量 TIME_WAIT 和端口耗尽 - 用
ss -s | grep ESTAB实时观察真实连接数,确认瓶颈在 Nginx 还是后端或系统资源
典型弹幕 location 配置示例
假设前端访问 wss://live.example.com/danmaku,后端 WebSocket 服务运行在 127.0.0.1:8081:
location /danmaku {
proxy_pass http://127.0.0.1:8081;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_buffering off;
proxy_cache off;
proxy_read_timeout 86400;
proxy_send_timeout 86400;
}











