mod_proxy_wstunnel 的 Apache 负载平衡器?

mod_proxy_wstunnel 的 Apache 负载平衡器?

我们正在开发一个 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]

相关内容