Apache实现WebSocket长连接转发的核心是明确识别并透传协议升级过程,必须启用mod_proxy_wstunnel模块、使用ws://或wss://协议前缀、强制透传Upgrade和Connection头、协同调优Timeout与ProxyTimeout超时参数,缺一将导致握手成功但后续帧传输异常或静默断连。

Apache 实现 WebSocket 长连接转发,核心不是“加个 ProxyPass 就行”,而是让 Apache 明确识别并透传协议升级过程。关键在模块启用、协议前缀、头透传和超时协同——缺一环,连接就会握手成功但秒断。
必须启用并验证 mod_proxy_wstunnel 模块
WebSocket 握手依赖 Upgrade: websocket 和 Connection: upgrade 两个 hop-by-hop 头,普通 proxy 模块会过滤掉它们。只有 mod_proxy_wstunnel 能正确处理 ws:// 或 wss:// 流量。
- 检查是否已加载:
httpd -M | grep -E "(proxy|wstunnel)",输出中必须含proxy_wstunnel_module、proxy_module、proxy_http_module - 若缺失,在
httpd.conf或模块启用目录中添加:LoadModule proxy_wstunnel_module modules/mod_proxy_wstunnel.so - 重启前务必运行
apachectl configtest,否则配置错误只报模糊的 “Invalid argument”
ProxyPass 必须用 ws:// 或 wss:// 协议前缀
写成 ProxyPass /ws/ http://backend:8080/ws/ 是常见错误——这会让 Apache 走 mod_proxy_http,握手虽能完成,后续帧(如 ping/pong)会被丢弃或乱序,表现为静默断连。
- 正确写法(路径末尾 / 必须一致):
ProxyPass /ws/ ws://127.0.0.1:8080/ws/ProxyPassReverse /ws/ ws://127.0.0.1:8080/ws/ - 若前端是 HTTPS 站点且用 wss://,Apache 需配 SSL 证书;后端可仍用 ws://(SSL 终止在 Apache),此时 ProxyPass 仍写
ws://,不可写wss://(除非后端真跑 TLS) - 不要加
retry=0、timeout=等 HTTP 专用参数,mod_proxy_wstunnel不支持,会导致配置校验失败
强制透传 Upgrade 和 Connection 请求头
即使启用了 wstunnel 模块,Apache 默认仍可能清洗 hop-by-hop 头。需显式声明保留:
- 在虚拟主机或目录配置中添加:
RequestHeader set Connection "upgrade"RequestHeader set Upgrade "websocket" - 禁用响应头篡改干扰会话:
ProxyPassReverseCookieDomain .example.com example.comProxyPassReverseCookiePath /ws/ /ws/(按实际路径调整) - 若使用负载均衡(
balancer),确保健康检查路径避开/ws/,避免探针误触发断连
超时与连接保活必须双调优
WebSocket 是长生命周期 TCP 连接,而 Apache 默认 Timeout 和 ProxyTimeout 均为 60 秒,空闲即断——后端无感知,客户端突现 “connection closed”。
- 在 WebSocket 专用虚拟主机内设置:
Timeout 3600ProxyTimeout 3600 - 启用 KeepAlive 并延长其生命周期:
KeepAlive OnKeepAliveTimeout 300MaxKeepAliveRequests 0(不限制请求数,适配单连接多帧场景) - MPM 模式建议切为
event:prefork 下每个连接占一个进程,高并发易 OOM;event支持异步 I/O,千级连接更稳(Ubuntu/Debian 可用a2dismod mpm_prefork && a2enmod mpm_event切换)


















