apache不处理websocket,仅靠mod_proxy_wstunnel透传握手并维持隧道;必须启用mod_proxy、mod_proxy_http、mod_proxy_wstunnel三模块,proxypass用ws://或wss://前缀,timeout与proxytimeout同步设为3600,并强制透传upgrade和connection头。
apache 本身不“处理”websocket,而是靠 mod_proxy_wstunnel 模块透传握手并维持隧道。配置成败不取决于 servername 写得对不对,而在于模块启用、协议前缀、超时设置和头透传这四个关键点是否全部到位。
必须启用三个核心模块
缺一不可,否则 ProxyPass 写成 ws:// 也无效:
-
mod_proxy:代理基础框架,所有代理功能依赖它 -
mod_proxy_http:mod_proxy_wstunnel内部调用它建立底层连接,不是可选项 -
mod_proxy_wstunnel:唯一能识别Upgrade: websocket并触发隧道逻辑的模块
检查是否已加载(Linux/macOS):httpd -M | grep -E "(proxy|wstunnel)"
应看到三者状态均为 shared。
Debian/Ubuntu 用户可直接运行:sudo a2enmod proxy proxy_http proxy_wstunnel && sudo systemctl restart apache2
ProxyPass 必须用 ws:// 或 wss:// 前缀
这是触发隧道的唯一开关。写成 http:// 看似能握手成功,但后续帧会被静默丢弃,典型表现是连接几秒后断开(1006 错误)。
正确写法示例(注意路径末尾 / 必须严格一致):
<virtualhost><br> ServerName example.com<br> ProxyPass "/ws/" "ws://127.0.0.1:8080/ws/"<br> ProxyPassReverse "/ws/" "ws://127.0.0.1:8080/ws/"<br></virtualhost>
若前端是 HTTPS 站点且用 wss://,Apache 需配置 SSL 证书,后端仍可用 ws://(SSL 终止在 Apache)。
Timeout 和 ProxyTimeout 必须同步设为 3600
默认 60 秒超时会主动 kill 空闲连接,导致“静默掉线”。这不是后端问题,是 Apache 自己断的。
安全更新和维护 CLI Proxy API(CPA)部署与配置。用于 CPA 镜像升级、配置变更、认证目录兼容修复、上线验证与回滚。适用于用户提到“CPA 更新/升级/配置改了/容器重建/回滚”等场景。
在对应 <virtualhost></virtualhost> 块中添加:
Timeout 3600<br>ProxyTimeout 3600
两个值必须相等且同时设置:前者影响整体请求生命周期,后者控制 socket 级超时。不建议全局修改,只在 WebSocket 专用站点中覆盖。
强制透传 Upgrade 和 Connection 头
这两个是 hop-by-hop 头,Apache 默认可能清洗,导致浏览器收不到 101 Switching Protocols 响应。
添加以下配置确保透传:
RequestHeader set Upgrade "websocket"<br>RequestHeader set Connection "upgrade"
同时避免添加 retry=0、timeout= 等 HTTP 专用参数——mod_proxy_wstunnel 不支持,加了会导致校验失败。










