我面临着关于粘性会话的Apache mod_proxy_balancer的一些问题。
我们在Java上开发了一个在Tomcat上运行的RESTful webservice。实际的后端使用Acegi安全性,使用Auth Basic身份验证。
架构是(抱歉我是新用户,我无法发布图片):
--------------------
|Java Reverse Proxy|
--------------------
|
--------------------
|Apache load balancer|
--------------------
|
--------|--------
| |
-------- --------
|tomcat1| |tomcat2|
-------- --------
我们有这个" Java反向代理"执行各种商业活动。它还在Tomcat上执行基本身份验证(Tomcat1,Tomcat2)。
最终用户调用以下网址:http:/// a / b?username = foo& password = bar& session = xxx
然后,反向代理将请求代理到Apache,并将凭据作为Basic Auth令牌发送。
最终用户有三个不同的网址:
http://<java reverse proxy domain>/service1
http://<java reverse proxy domain>/service2
http://<java reverse proxy domain>/service3
只有service1和service2受Acegi保护。 service3是匿名访问的(这是一项要求)。
我们在Apache中具有以下配置来执行负载平衡:
<Proxy balancer://cluster>
Header set Cache-Control no-cache
Header set Pragma no-cache
BalancerMember http://xxx:9671 route=server1
BalancerMember http://xxx:9672 route=server2
</Proxy>
ProxyPreserveHost On
ProxyPass / balancer://cluster/ stickysession=JSESSIONID
ProxyPassReverse / balancer://cluster/ stickysession=JSESSIONID
在第一次调用service1时,然后将JSESSIONID返回给用户,然后他将此会话信息作为请求的一部分发送(在查询字符串中,会话参数)
为了维护后端tomcats(tomcat1,tomcat2)中的会话状态,java反向代理从查询字符串中获取会话,并将其作为JSESSIONID cookie发送给代理的tomcats。
对于基本保护的身份验证的URL,一切都很好。但是当用户调用第三个url(公共可用)时,Apache无法正确执行负载平衡。
例如,当我调用服务1或2时,我得到以下Apache日志:
[Wed Feb 22 10:48:52 2012] [debug] mod_proxy_balancer.c(280): proxy: BALANCER: Found value "3FB8F8135173BBBE78E5E4BBD6F5C8FB" for stickysession JSESSIONID
[Wed Feb 22 10:48:52 2012] [debug] mod_proxy_balancer.c(1003): proxy: Entering byrequests for BALANCER (balancer://cluster)
[Wed Feb 22 10:48:52 2012] [debug] mod_proxy_balancer.c(1046): proxy: byrequests selected worker "http://xxx:9672" : busy 0 : lbstatus 1
这完全没问题,因为请求的目标是tomcat2。
但是当我打电话给service3时,我得到了:
[Wed Feb 22 10:49:27 2012] [debug] mod_proxy_balancer.c(280): proxy: BALANCER: Found value "3FB8F8135173BBBE78E5E4BBD6F5C8FB" for stickysession JSESSIONID
[Wed Feb 22 10:49:27 2012] [debug] mod_proxy_balancer.c(1003): proxy: Entering byrequests for BALANCER (balancer://cluster)
[Wed Feb 22 10:49:27 2012] [debug] mod_proxy_balancer.c(1046): proxy: byrequests selected worker "http://xxx:9671" : busy 0 : lbstatus 0
正如您所看到的,即使JSESSIONID cookie相同,Apache也会将请求发送到错误的tomcat(此处为tomcat1)。
可能是service3的url不需要Auth Basic身份验证,而service1和service2在哪里呢?
我很确定我做错了什么,但我已经找了很长时间了,我无法让它发挥作用。
非常感谢您的帮助。
由于
答案 0 :(得分:6)
我没有在JSESSIONID上看到jvmRoute后缀。 mod_proxy使用jvmRoute将粘性会话正确路由到Tomcat实例。 jvmRoute在tomcat服务器配置中声明(其中每个服务器实例都有自己唯一的jvmRoute标识符。
答案 1 :(得分:1)
我遇到了同样的问题,并通过修改以下行解决了这个问题 -
ProxyPass /test balancer://mycluster stickysession=JSESSIONID|jsessionid scolonpathdelim=On
<Proxy balancer://mycluster>
BalancerMember http://192.168.1.2:80 route=node1
BalancerMember http://192.168.1.3:80 route=node2
</Proxy>
请注意配置scolonpathdelim = On 参考 - http://httpd.apache.org/docs/2.2/mod/mod_proxy_balancer.html
答案 2 :(得分:0)
也许这会有所帮助。这是我在Web服务器上的配置:
<Proxy balancer://hybriscluster>
BalancerMember ajp://tomcatServer1:8009 route=tomcat1 keepalive=On ping=5 max=200 ttl=120
BalancerMember ajp://tomcatServer2:8009 route=tomcat2 keepalive=On ping=5 max=200 ttl=120
ProxySet stickysession=JSESSIONID|jsessionid lbmethod=byrequests timeout=60
</Proxy>
在tomcat Server 1的server.xml中配置:
<Engine name="Catalina" defaultHost="localhost" jvmRoute="tomcat1"}">