Nginx反向代理Java WebSocket服务需显式透传Upgrade头并维持长连接:必须配置proxy_http_version 1.1、proxy_set_header Upgrade $http_upgrade、proxy_set_header Connection "upgrade",并设置合理的proxy_read_timeout/proxy_send_timeout、proxy_buffering off和tcp_nodelay on。

Java 应用(如 Spring Boot、Netty 或 Tomcat 部署的 WebSocket 服务)通过 Nginx 反向代理时,不能只靠 proxy_pass 就完事。Nginx 默认按 HTTP 短连接处理,会截断升级头、关闭空闲连接,导致 WebSocket 握手失败(400 错误)或连接秒断。关键在于显式透传协议升级信号并维持长连接生命周期。
必须配置的握手透传参数
WebSocket 握手依赖 HTTP/1.1 的 Upgrade 流程,Nginx 默认不转发逐跳(hop-by-hop)头部,必须手动声明:
- proxy_http_version 1.1:硬性前提。HTTP/1.0 不支持 Upgrade,缺了这句,后端收不到升级请求,直接拒连
-
proxy_set_header Upgrade $http_upgrade:用变量而非写死
"websocket",兼容 Spring WebSocket、STOMP 等不同子协议 -
proxy_set_header Connection "upgrade":固定字符串
"upgrade",不是$http_connection(后者可能是keep-alive,会掩盖升级意图)
防止连接被静默中断的超时与缓冲设置
Java 后端(如 Spring Boot 的 WebSocketHandler)通常每 30 秒发一次 ping,Nginx 默认 proxy_read_timeout 60s 看似够用,但实际极易触发断连:
- proxy_read_timeout 和 proxy_send_timeout 均设为 ≥ 后端最大心跳间隔 × 1.5(例如后端 ping 间隔 30s,建议设为 45–300s;生产环境常设 86400)
- proxy_buffering off:禁用响应缓冲,避免多个 TEXT 帧被合并发送,影响实时性或引发粘包
- tcp_nodelay on:绕过 Nagle 算法,让小数据(如心跳、光标移动)立即发出,降低延迟
Java 场景下的补充要点
Spring Boot 默认使用 /ws 或 /ws/** 路径,且可能依赖 Origin 或 Host 头做校验:
立即学习“Java免费学习笔记(深入)”;
- proxy_set_header Host $host 和 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for 必须带上,否则 Spring Security 或跨域过滤器可能拦截
-
若用 WSS(HTTPS → Java HTTP):需加
proxy_set_header X-Forwarded-Proto $scheme,让 Java 应用感知原始协议,避免重定向循环或 URL 构造错误 - 禁用 proxy_cache、proxy_redirect 等短连接优化项:这些对长连接无意义,反而干扰帧流
一个典型 location 示例(适配 Spring Boot WebSocket)
假设 Java 服务运行在 http://localhost:8080,WebSocket 端点为 /ws/chat:
location /ws/ {
proxy_pass http://localhost:8080/;
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_read_timeout 300;
proxy_send_timeout 300;
proxy_buffering off;
tcp_nodelay on;
}


















