我目前正在开发一个websocket应用程序,它被部署在Tomcat服务器上。 由于用户数量庞大,我想将工作负载分配给多个Tomcat实例。 我决定使用Apache进行负载平衡。
现在我有一个Apache负载平衡和WebSockets请求的粘性会话的执行问题。 这是我的Apacheconfiguration:
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/
第一个https请求平衡到端口8443.升级后的wss请求也被转发到8443。
第二个https请求包含第一个请求的sessionID: https://…&sid = C28C13EEEC525D203F8CA4E827605E0B.jvm1
正如我可以在Apache日志文件中看到的,这个sessionID被评估为stickySession:
…发现值C28C13EEEC525D203F8CA4E827605E0B.jvm1 for stickysession sid
…find路线jvm1
… balancer:// http-localhost:worker(htttps://mcsgest1.desy.de:8443 / Whiteboard /)重写为htttps://mcsgest1.desy.de:8443 / Whiteboard //?file = octocenter。 XML&地址= ///&SID = C28C13EEEC525D203F8CA4E827605E0B.jvm1
第二个https请求仍在端口8443上,但升级到websocket协议后,ws-balancer不会评估sessionID并重写为8444:
… balancer:// ws-localhost:worker(wss://mcsgest1.desy.de:8444 / Whiteboard /)重写为wss://mcsgest1.desy.de:8444 / Whiteboard // whiteboardendpoint
在Apacheconfiguration中还需要更改什么来启用stickysession以及wss协议? 我真的需要两个平衡器(http和ws)才能使websocket平衡吗?
您不需要为websokets单独的平衡器,因为最初的http请求已经有http cookie并且属于正确的实例。
您只需检测连接升级并手动路由请求,具体取决于cookie的粘滞部分
确保你加载代理模块的websokets – mod_proxy_wstunnel
例如
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
说明:
# 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]