nginx反向代理需显式透传upgrade机制:设proxy_http_version 1.1,用map动态设置connection头,禁用缓冲并调长超时,确保路径、协议及host头与后端严格一致。

在 Nginx 中处理反向代理下的特殊协议升级请求,核心是让 HTTP 连接能正确切换到 WebSocket、gRPC 或其他基于 Upgrade 机制的协议。这不是简单转发就能完成的事,关键在于显式透传协议升级所需的“逐跳头部”,并确保连接生命周期与协议语义一致。
必须启用 HTTP/1.1 并透传 Upgrade 头
WebSocket 握手依赖 HTTP/1.1 的 Upgrade 机制,而 Nginx 默认可能以 HTTP/1.0 转发请求,或直接过滤掉非标准头。需在 location 块中明确配置:
- proxy_http_version 1.1; —— 强制使用 HTTP/1.1,这是协议升级的前提
- proxy_set_header Upgrade $http_upgrade; —— 将客户端原始的 Upgrade 头(如 websocket)原样传给后端
Connection 头必须动态设置,不能写死
Connection 是逐跳头,Nginx 不会自动转发。若硬写 proxy_set_header Connection "upgrade";,会导致普通 HTTP 请求也被错误标记为升级请求,引发后端异常响应(如返回 400 或 200)。正确做法是用 map 指令动态判断:
- 在 http 块中定义:
map $http_upgrade $connection_upgrade {<br> default upgrade;<br> '' close;<br>} - 再在 location 中使用:
proxy_set_header Connection $connection_upgrade;
超时与缓冲需针对性调优
WebSocket 是长连接,Nginx 默认的 60 秒超时和启用缓冲的行为会中断通信:
- proxy_read_timeout 3600; 和 proxy_send_timeout 3600; —— 避免空闲连接被主动关闭(单位:秒,按业务需要调整)
- proxy_buffering off; —— 禁用响应缓冲,防止帧数据被攒批发送,影响实时性
- 若后端服务部署在非标端口(如 8080、3000),proxy_pass 必须写全地址,例如
proxy_pass http://127.0.0.1:8080;,不能省略端口
注意路径、协议与 Host 头的一致性
很多 403、400 或 200 错误并非配置缺失,而是上下文不匹配:
- 确保 Nginx location 路径(如
/ws)与后端实际监听的路径完全一致 - SSL 终止在 Nginx 时,后端需通过
X-Forwarded-Proto判断是否为 wss;若后端只接受 wss 却收到http,会拒绝握手 - 必要时透传 Host:proxy_set_header Host $host; 或带端口的
$host:$server_port,避免后端因 Host 不匹配而拒收











