Nginx代理WebSocket必须在精准匹配路径的location块中同时配置三项协议升级(proxy_http_version 1.1、proxy_set_header Upgrade $http_upgrade、proxy_set_header Connection "upgrade")和两项保活控制(proxy_read_timeout 86400、proxy_send_timeout 86400),缺一不可。

WebSocket 不是“加个参数”就能通的,关键在于 location 块里必须同时满足五项硬性要求:三项协议升级动作 + 两项连接保活控制,缺一不可,且必须写在路径明确的 location 中,不能塞进 location / { } 里。
必须写的三项协议升级配置
WebSocket 握手依赖 HTTP/1.1 的协议切换机制,Nginx 默认会丢掉关键头,必须显式透传:
- proxy_http_version 1.1; —— 强制用 HTTP/1.1(HTTP/1.0 不支持 Upgrade)
-
proxy_set_header Upgrade $http_upgrade; —— 把客户端发来的
Upgrade: websocket原样转发 -
proxy_set_header Connection "upgrade"; —— 注意是固定字符串
"upgrade",不是变量;这是触发 Nginx 协议切换的开关
必须调的两项连接保活参数
默认缓冲和超时策略会直接断开 WebSocket 长连接,必须针对性调整:
- proxy_read_timeout 86400; —— 设为 24 小时(或至少 3600),防空闲连接被主动关闭
- proxy_send_timeout 86400; —— 同步设大,保障后端推送不中断
- (可选但推荐)proxy_buffering off; —— 禁用缓冲,避免帧粘包或延迟,尤其对实时性要求高的场景
路径匹配要精准,别靠猜
WebSocket 流量必须走专用路径,且 location 必须能真正匹配到请求 URI:
- 推荐写法:
location /ws { ... }或location /api/ws { ... }—— 前缀匹配,能覆盖/ws、/ws/chat、/ws/v2/health等所有子路径 - 避免写成
location / { ... }里混着配 WebSocket,容易被覆盖或忽略升级头 - 若需更灵活匹配(如带多级子路径),可用正则:
location ~ ^/ws(/.*)?$ { ... } - 前端 new WebSocket("wss://domain.com/ws") 的路径必须和 location 完全一致
增强健壮性的可选操作
加一层校验,防止非 WebSocket 请求误入:
- if ($http_upgrade != "websocket") { return 403; } —— 放在 location 块内,拦截非法升级请求
- 全局定义 map(放在 http {} 块里):
map $http_upgrade $connection_upgrade { default upgrade; '' close; },再用proxy_set_header Connection $connection_upgrade;替代硬编码,更规范


















