3

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!

Shadowman
  • 71
  • 1
  • 8

3 Answers3

4

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.

user380440
  • 41
  • 2
0

I'm not certain whether this can or cannot be done with Apache + mod_proxy.

As far as alternatives to Apache, there are other commercial solutions that provide load balancing and Websocket support. Shaka Technologies' Ishlangu Load Balancer ADC supports transparent (zero-configuration) websockets. I believe F5 BIG-IP do as well.

0

Since 2.4.5 there is the mod_proxy_wstunnel module which provides WebSocket (ws://) and secure WebSocket (wss://) protocol support to mod_proxy. However wss is only useable with 2.4.10+ due to a bug in earlier versions (PR55320).

Even though not explicitly mentioned in the documentation, you can use the ws(s) protocol with mod_proxy (and mod_proxy_balancer) like any other supported protocols. Just make sure that mod_proxy_wstunnel is actually loaded.

From the description it is not clear if there are any useable errors in the Apache logs. Are you sure that you web application only accesses /ws? There might be a path mismatch, /ws/anything will end up as /MyContextPath/myWebSocketEndpoint/anything on your WebSocket server which is probably not what you want.

If this is the case, you'd rather need:

<Proxy balancer://myBalancer>
    BalancerMember ws://localhost:9080
    BalancerMember ws://localhost:19080
</Proxy>

RewriteEngine On
RewriteRule /ws(/.*)? balancer://myBalancer/MyContextPath/myWebSocketEndpoint [P,L]
PeterPramb
  • 501
  • 3
  • 3