我在使用Apache mod_proxy_balancer时遇到了一些关于粘性会话的问题。
我们在Tomcat上开发了一个RESTful Web服务。实际的后端使用Acegi安全框架,并采用基本身份验证。
整个架构如下(很抱歉,我是新用户,无法发布图片):
--------------------
|Java Reverse Proxy|
--------------------
|
--------------------
|Apache load balancer|
--------------------
|
--------|--------
| |
-------- --------
|tomcat1| |tomcat2|
-------- --------
我们有一个"Java反向代理",用于执行各种业务操作。它还在Tomcat(Tomcat1、Tomcat2)上执行基本身份验证。最终用户调用诸如:http:///a/b?username=foo&password=bar&session=xxx 的URL。
反向代理然后代理请求到Apache,并将凭据作为基本身份验证令牌发送。
最终用户有三个不同的URL:
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无法正确执行负载平衡。
例如,当我调用service1或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不需要基本身份验证,而service1和service2需要。
我很确定我做错了什么,但我已经找了很长时间,还是无法让它工作。
非常感谢您的帮助。
谢谢