apache代理websocket需启用mod_proxy_wstunnel模块,proxypass必须用ws://或wss://前缀,设timeout与proxytimeout均为3600,并透传upgrade/connection头。

Apache 本身不处理 WebSocket 握手,它只是把 Upgrade 请求“隧道化”转发给后端 Java 应用(如 Tomcat、Spring Boot 内嵌容器)。关键不是改 Java 代码,而是 Apache 的代理配置必须精准匹配 WebSocket 协议升级机制。
必须启用 mod_proxy_wstunnel 模块
这是唯一能识别 Upgrade: websocket 并建立持久隧道的模块。仅靠 mod_proxy 和 mod_proxy_http 无法完成握手——它们会把 WebSocket 请求当作普通 HTTP 处理,导致 101 响应丢失、连接被静默关闭。
- 检查是否已加载:
httpd -M | grep wstunnel(Linux/macOS)或httpd -M | findstr wstunnel(Windows) - 未启用时,在
httpd.conf中取消以下三行注释:LoadModule proxy_module modules/mod_proxy.soLoadModule proxy_http_module modules/mod_proxy_http.soLoadModule proxy_wstunnel_module modules/mod_proxy_wstunnel.so - Ubuntu/Debian 用户可直接运行:
sudo a2enmod proxy proxy_http proxy_wstunnel
ProxyPass 必须用 ws:// 或 wss:// 前缀
协议前缀是触发隧道模式的开关。哪怕后端是 Tomcat 的 ws://localhost:8080,Apache 配置里也必须写 ws://,不能写 http://——否则走的是 HTTP 代理流程,握手后帧全丢,前端报错 1006。
- 典型配置(假设 Java 应用 WebSocket 端点路径为
/ws):ProxyPass /ws ws://127.0.0.1:8080/wsProxyPassReverse /ws ws://127.0.0.1:8080/ws - 路径末尾斜杠必须严格一致:如果后端监听
/ws/,这里也要写/ws/,否则可能 404 - 若前端用
wss://,Apache 必须启用 SSL(VirtualHost *:443),并配置证书;后端仍可用ws://(SSL 终止在 Apache)
超时与头透传必须同步设置
WebSocket 是长连接,Apache 默认 60 秒超时会主动断开空闲连接,造成“静默掉线”。同时,Upgrade 和 Connection 是 hop-by-hop 头,Apache 默认可能清洗,导致浏览器收不到 101 响应。
- 在对应
<virtualhost></virtualhost>块中添加:Timeout 3600ProxyTimeout 3600
两个值必须相等且只在此站点生效,不建议全局修改 - 强制透传关键头(Apache 2.4.10+ 支持):
ProxyPreserveHost OnRequestHeader set Connection "upgrade"RequestHeader set Upgrade "websocket"
规则顺序和后端兼容性要点
WebSocket 路径代理规则必须放在通用代理规则(如 ProxyPass / http://...)之前,否则请求会被提前截获走 HTTP 流程。
- Tomcat 用户注意:确保应用中 WebSocket 端点已正确注册(如 Spring Boot 的
@EnableWebSocket+WebSocketConfigurer),且未被 Security 配置拦截路径 - 若使用 mod_security,需放行
Upgrade头,否则握手请求会被拦截 - 保持
KeepAlive On,KeepAliveTimeout建议 ≥60 秒,避免连接池过早释放
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











