apache实现websocket长连接需启用mod_proxy_wstunnel模块,proxypass必须用ws://或wss://前缀,统一路径末尾斜杠,同时设置timeout和proxytimeout为3600,并配置stickysession=routeid实现会话粘滞。

Apache本身不处理WebSocket连接状态,它只负责把客户端的Upgrade请求透传给后端,并维持TCP层的长连接通道。保活的关键在于“不干扰、不中断、不超时”,而不是主动管理状态。
确保mod_proxy_wstunnel模块正确启用
这是所有配置的前提。Apache必须明确识别并走WebSocket专用代理路径,否则会按普通HTTP处理,导致握手成功但后续帧传输异常。
- 检查是否已加载三个必需模块:mod_proxy、mod_proxy_http、mod_proxy_wstunnel,命令为
httpd -M | grep -E "(proxy|wstunnel)" - 若缺失,编辑
httpd.conf或对应load文件,添加三行:LoadModule proxy_module modules/mod_proxy.soLoadModule proxy_http_module modules/mod_proxy_http.soLoadModule proxy_wstunnel_module modules/mod_proxy_wstunnel.so - 重启前务必执行
apachectl configtest,避免因模块缺失导致启动失败且错误提示模糊
ProxyPass必须使用ws://或wss://协议前缀
这是最容易出错的一环。用http://前缀会让Apache走mod_proxy_http流程,无法透传Upgrade头,连接会在首次ping后静默断开。
FastAPI + Flask 混合部署最佳实践,解决路由定义、API 代理等常见问题,适用于同时运行 FastAPI API 与 Flask 前端的场景。
- 正确写法示例:
ProxyPass /ws/ ws://127.0.0.1:8080/ws/ProxyPassReverse /ws/ ws://127.0.0.1:8080/ws/ - 路径末尾斜杠必须严格一致,否则
Sec-WebSocket-Location头重写错误,浏览器会拒绝连接 - 如使用WSS,前端站点必须是HTTPS,Apache自身需配置SSL证书(不能仅靠后端提供)
显式延长超时并禁用干扰行为
默认60秒的Timeout和ProxyTimeout是WebSocket长连接的最大杀手。空闲超时由Apache主动断连,后端完全无感知。
- 在WebSocket专用虚拟主机中设置:
Timeout 3600ProxyTimeout 3600 - 这两个值必须同时设,因为
mod_proxy_wstunnel底层依赖socket级超时,仅改其一无效 - 禁用所有面向短连接的优化:不加
retry=0等参数(mod_proxy_wstunnel不支持),不启用缓存或buffering
配合后端实现双向心跳与会话粘滞
Apache只管通道畅通,真正的连接活性靠后端心跳维持;多实例部署时还需确保同一连接始终落在同一台机器上。
- 后端服务(如Swoole、Spring Boot WebSocket)需主动发送
Ping帧或约定JSON心跳消息(如{"type":"ping"}),客户端响应Pong - 负载均衡场景下,在
ProxyPass中加入stickysession=routeid,并让后端在握手成功后通过Set-Cookie或响应头注入唯一routeid - 建议心跳间隔设为30秒,超时阈值设为60秒,确保小于常见NAT网关的120–300秒空闲限制










