2016-06-01 6 views
3

Ich entwickle gerade eine WebSocket-Anwendung, die auf einem Tomcat-Server bereitgestellt wird. Aufgrund der großen Anzahl von Benutzern möchte ich die Arbeitslast auf mehrere Tomcat-Instanzen verteilen. Ich entschied mich dafür, Apache für den Lastausgleich zu verwenden.Apache Lastausgleich Tomcat Websocket

Jetzt habe ich ein Problem mit der Implementierung von Apache Load Balancing und Sticky-Sitzung für WebSockets Anfragen. Dies ist meine Apache-Konfiguration:

ProxyRequests off 
SSLProxyEngine on 
RewriteEngine On 

<Proxy balancer://http-localhost/> 
    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 
</Proxy> 

<Proxy balancer://ws-localhost/> 
    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 
</Proxy> 

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/ 

Die erste https Anfrage nach Port 8443. Die aktualisierte WSS Anfrage auch zu 8443. weitergeleitet wird

Die zweite HTTPS-Anforderung der sessionID der ersten Anforderung enthält ausgeglichen ist:

... Foun: https://...&sid=C28C13EEEC525D203F8CA4E827605E0B.jvm1

Wie ich in der Apache-Protokolldatei sehen können, ist dies sessionID für stickySession bewertet d Wert C28C13EEEC525D203F8CA4E827605E0B.jvm1 für stickysession sid

... Gefunden Route jvm1

... Balancer: // http-localhost: Arbeiter (htttps: //mcsgest1.desy.de: 8443/Whiteboard /) neu geschrieben htttps: //mcsgest1.desy.de: 8443/Whiteboard // file = octocenter.xml & Adresse = /// & sid = C28C13EEEC525D203F8CA4E827605E0B.jvm1

Die zweite hTTPS-Anforderung noch an Port 8443, aber nach dem Upgrade auf das Websocket-Protokoll funktioniert der ws-Balancer nicht die sessionID bewerten und neu geschrieben zu 8444:

... Balancer: // ws-localhost: Arbeiter (WSS: //mcsgest1.desy.de: 8444/Whiteboard /) neu geschrieben wss : //mcsgest1.desy.de: 8444/Whiteboard // whiteboardendpoint

Was in der Apache-Konfiguration muss ich ändern stickysession auch für WSS-Protokoll zu aktivieren? Brauche ich wirklich zwei Balancer (http und ws), um die WebSockets zu balancieren?

Antwort

2

Sie benötigen keinen separaten Balancer für Websockets, da die erste HTTP-Anfrage bereits einen HTTP-Cookie hat und zur richtigen Instanz gehört.

Sie müssen nur Verbindung aktualisieren erkennen und je manuell Anfrage Route von klebrigem Teil des Cookies

Stellen Sie sicher, dass Proxy-Modul für websokets laden - mod_proxy_wstunnel

zum Beispiel

SSLProxyEngine on 
RewriteEngine On 

<Proxy balancer://http-localhost/> 
    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 
</Proxy> 

RewriteCond %{HTTP:UPGRADE} ^WebSocket$ [NC] 
RewriteCond %{HTTP:CONNECTION} Upgrade$ [NC] 
RewriteCond %{HTTP_COOKIE} ^.*(JSESSIONID|sid)=([^=]*)\.jvm1 [NC] 
RewriteRule .* wss://mcsgest1.desy.de:8443%{REQUEST_URI} [P,L] 

RewriteCond %{HTTP:UPGRADE} ^WebSocket$ [NC] 
RewriteCond %{HTTP:CONNECTION} Upgrade$ [NC] 
RewriteCond %{HTTP_COOKIE} ^.*(JSESSIONID|sid)=([^=]*)\.jvm2 [NC] 
RewriteRule .* wss://mcsgest1.desy.de:8444%{REQUEST_URI} [P,L] 

RewriteRule /jddd/(.*) balancer://http-localhost$1 [P,L] 

ProxyPreserveHost On 
ProxyRequests Off 

ProxyPass /jddd/ balancer://http-localhost 
ProxyPassReverse /jddd/ balancer://http-localhost 

Erläuterung:

# if header upgrade = WebSocket 
RewriteCond %{HTTP:UPGRADE} ^WebSocket$ [NC] 
# and header connection contains Upgrade (header may be like this: connection=keep-alive, upgrade) 
RewriteCond %{HTTP:CONNECTION} Upgrade$ [NC] 
# and header cookie contains JSESSIONID or sid, ending with sticky part - .jvm1 in that case 
RewriteCond %{HTTP_COOKIE} ^.*(JSESSIONID|sid)=([^=]*)\.jvm1 [NC] 
#than we route request to application server via mod_proxy (P flag) and end rewrite rule check 
RewriteRule .* wss://mcsgest1.desy.de:8443%{REQUEST_URI} [P]