我们正在开发一个 JavaEE 7 应用程序,该应用程序将部署在 JBoss/Wildfly 上,并将大量使用 Web 套接字。我们正在使用Web 套接字支持,并且我们已设法通过在 Apache 2.4 上mod_proxy_wstunnel
使用来启动和运行代理配置:mod_cluster
互联网 -> Apache HTTPD -> Wildfly
我们现在面临的是集群化此应用程序的问题。为了实现性能可扩展性和高可用性,我们将至少启动并运行 4 个节点。我尝试创建一个<Proxy />
包含 2 个成员服务器的元素来实现这一点。它看起来像这样:
<VirtualHost *:80>
...
<Proxy balancer://myBalancer>
BalancerMember ws://localhost:9080
BalancerMember ws://localhost:19080
</Proxy>
<Location /ws>
...
ProxyPass balancer://myBalancer/MyContextPath/myWebSocketEndpoint
ProxyPassReverse balancer://myBalancer/MyContextPath/myWebSocketEndpoint
</Location>
</VirtualHost>
但是,这不起作用。尝试打开路径上的 Web 套接字时,JavaScript 中总是出现连接错误。http://localhost/ws
我快速浏览了文档mod_proxy_balancer
,发现它声明支持 HTTP、FTP 和 AJP13 协议。有没有办法平衡 Web 套接字和 WS 协议的负载?或者这是一个完全不受支持的配置?我可以利用哪些其他替代方案来实现这一点?显然,将单个 Web 套接字服务器作为我们的生产端点是不可接受的,因为它代表了单点故障。如果您能提供任何建议,我将不胜感激!
答案1
根据 Apache 官方文档: https://httpd.apache.org/docs/2.4/en/mod/mod_proxy_balancer.html
mod_proxy_balancer 需要 mod_proxy 的服务,它为所有支持的协议提供负载平衡。最重要的是:
- HTTP,使用 mod_proxy_http
- FTP,使用 mod_proxy_ftp
- AJP13,使用 mod_proxy_ajp
- WebSocket,使用 mod_proxy_wstunnel
定义你的平衡器:
<Proxy balancer://wsBalancer>
BalancerMember ws://host1:9080 route=jvm1
BalancerMember ws://host2:9080 route=jvm2
ProxySet lbmethod=byrequests stickysession=JSESSIONID
</Proxy>
然后进行 ws 调用以到达该平衡器:
<LocationMatch "^/cometd/.*">
ProxyPass "balancer://wsBalancer/" stickysession=JSESSIONID
</LocationMatch>
这里的 /cometd/ 是您的应用程序的 WS 上下文。
答案2
我不确定是否可以用 Apache + mod_proxy 来实现这一点。
至于 Apache 的替代品,还有其他商业解决方案提供负载平衡和 Websocket 支持。Shaka Technologies 的 Ishlangu 负载均衡器 ADC 支持透明(零配置)websocket。 我相信F5 大 IP也这样做。
答案3
自 2.4.5 起,mod_proxy_wstunnel 模块为 mod_proxy 提供 WebSocket (ws://) 和安全 WebSocket (wss://) 协议支持。然而,由于早期版本 (PR55320) 中存在错误,wss 仅适用于 2.4.10+。
尽管文档中没有明确提及,但您可以像使用任何其他受支持的协议一样将 ws(s) 协议与 mod_proxy(和 mod_proxy_balancer)一起使用。只需确保 mod_proxy_wstunnel 确实已加载即可。
从描述来看,不清楚 Apache 日志中是否有任何可用的错误。您确定您的 Web 应用程序仅访问 吗/ws
?可能存在路径不匹配,/ws/anything
最终会出现/MyContextPath/myWebSocketEndpoint/anything
在您的 WebSocket 服务器上,这可能不是您想要的。
如果是这样,您更需要:
<Proxy balancer://myBalancer>
BalancerMember ws://localhost:9080
BalancerMember ws://localhost:19080
</Proxy>
RewriteEngine On
RewriteRule /ws(/.*)? balancer://myBalancer/MyContextPath/myWebSocketEndpoint [P,L]