Apache load balancer for mod_proxy_wstunnel

apache-2.4clusterjbosssocketwildfly8

We are in the process of developing a JavaEE 7 application to be deployed on JBoss/Wildfly that will make extensive use of Web Sockets. We're using mod_proxy_wstunnel for web socket support, and we've managed to get a proxied configuration up and running through the use of mod_cluster on Apache 2.4:

Internet -> Apache HTTPD -> Wildfly

We are now faced with the issue of clustering this application. We will have at least 4 nodes up and running for both performance scalability and high-availability. I tried creating a <Proxy /> element with 2 member servers to accomplish this. It looked something like this:

<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>

This, however does not work. I always get connection errors in JavaScript when attempting to open the web socket at path http://localhost/ws. I took a quick glance at the documentation for mod_proxy_balancer and noticed that it declares support for the HTTP, FTP, and AJP13 protocols. Is there a way to load balance web sockets and the WS protocol as well? Or is this a completely unsupported configuration? What other alternatives could I leverage to accomplish this? Obviously, having a single web socket server as our production endpoint is unacceptable, as it represents a single point of failure. I'd GREATLY appreciate any advice you can give!

Best Answer

According Apache official documentation : https://httpd.apache.org/docs/2.4/en/mod/mod_proxy_balancer.html

mod_proxy_balancer requires the service of mod_proxy and it provides load balancing for all the supported protocols. The most important ones are:

  • HTTP, using mod_proxy_http
  • FTP, using mod_proxy_ftp
  • AJP13, using mod_proxy_ajp
  • WebSocket, using mod_proxy_wstunnel

to define your balancer :

<Proxy balancer://wsBalancer>
    BalancerMember ws://host1:9080 route=jvm1
    BalancerMember ws://host2:9080 route=jvm2
    ProxySet lbmethod=byrequests stickysession=JSESSIONID
</Proxy>

then make ws calls get to that balancer :

<LocationMatch "^/cometd/.*">
    ProxyPass "balancer://wsBalancer/" stickysession=JSESSIONID
</LocationMatch>   

Where here /cometd/ is the WS context of your application.

Related Topic