title: Apache load balance tomcat websocket
body: <p>I am currently developing a websocket application, which is deployed on a Tomcat server. Because of the huge number of users I would like to distribute the workload to multiple Tomcat instances. I decided to use Apache for load balancing.</p>
  
  <p>Now I have a problem with the implementation of Apache load balancing and sticky session for websockets requests. This is my Apache configuration:</p>
  
  <pre><code>ProxyRequests off
  SSLProxyEngine on
  RewriteEngine On
  
  &lt;Proxy balancer://http-localhost/&gt;
      BalancerMember  https://mcsgest1.desy.de:8443/Whiteboard/ route=jvm1 keepalive=On smax=1 connectiontimeout=10 retry=600 timeout=900 ttl=900
      BalancerMember  https://mcsgest1.desy.de:8444/Whiteboard/ route=jvm2 keepalive=On smax=1 connectiontimeout=10 retry=600 timeout=900 ttl=900
      ProxySet lbmethod=byrequests
      ProxySet stickysession=JSESSIONID|sid scolonpathdelim=On
  &lt;/Proxy&gt;
  
  &lt;Proxy balancer://ws-localhost/&gt;
      BalancerMember  wss://mcsgest1.desy.de:8443/Whiteboard/ route=jvm1 keepalive=On smax=1 connectiontimeout=10 retry=600 timeout=900 ttl=900
      BalancerMember  wss://mcsgest1.desy.de:8444/Whiteboard/ route=jvm2 keepalive=On smax=1 connectiontimeout=10 retry=600 timeout=900 ttl=900
      ProxySet lbmethod=byrequests
      ProxySet stickysession=JSESSIONID|sid scolonpathdelim=On
  &lt;/Proxy&gt;
  
  RewriteCond       %{HTTP:Upgrade} =websocket
  RewriteRule       /jddd/(.*)      balancer://ws-localhost/$1 [P,L]
  ProxyPassReverse  /jddd/          balancer://ws-localhost/
  RewriteCond       %{HTTP:Upgrade} !=websocket
  RewriteRule       /jddd/(.*)      balancer://http-localhost/$1 [P,L]
  ProxyPassReverse  /jddd/          balancer://http-localhost/
  </code></pre>
  
  <p>The first https request is balanced to Port 8443. The upgraded wss request is also forwarded to 8443.</p>
  
  <p>The second https request contains the sessionID of the first request:
  <a href="https://...&amp;sid=C28C13EEEC525D203F8CA4E827605E0B.jvm1" rel="nofollow">https://...&amp;sid=C28C13EEEC525D203F8CA4E827605E0B.jvm1</a></p>
  
  <p>As I can see in the Apache log file, this sessionID is evaluated for stickySession:</p>
  
  <blockquote>
    <p>...Found value C28C13EEEC525D203F8CA4E827605E0B.jvm1 for stickysession
    sid</p>
    
    <p>...Found route jvm1</p>
    
    <p>...balancer://http-localhost: worker
    (htttps://mcsgest1.desy.de:8443/Whiteboard/) rewritten to
    htttps://mcsgest1.desy.de:8443/Whiteboard//?file=octocenter.xml&amp;address=///&amp;sid=C28C13EEEC525D203F8CA4E827605E0B.jvm1</p>
  </blockquote>
  
  <p>The second https request is still on port 8443, but after upgrading to websocket protocol, the ws-balancer doesn't evaluate the sessionID and rewrites to 8444:</p>
  
  <blockquote>
    <p>...balancer://ws-localhost: worker
    (wss://mcsgest1.desy.de:8444/Whiteboard/) rewritten to
    wss://mcsgest1.desy.de:8444/Whiteboard//whiteboardendpoint</p>
  </blockquote>
  
  <p>What do I have to change in the Apache config to enable stickysession also for wss protocol? Do I really need two balancers (http and ws) to get websockets balanced?</p>