我在使用 Apache mod_proxy_balancer 时遇到了一些关于粘性会话的问题。
我们用 Java 开发了一个 RESTful Web 服务,在 Tomcat 上运行。实际的后端使用 Acegi 安全性和 Auth Basic 身份验证。
架构是(对不起,我是新用户,我不能发布图片):
--------------------
|Java Reverse Proxy|
--------------------
|
--------------------
|Apache load balancer|
--------------------
|
--------|--------
| |
-------- --------
|tomcat1| |tomcat2|
-------- --------
我们有这个“Java 反向代理”来执行各种业务。它还在 Tomcat(Tomcat1、Tomcat2)上执行 Basic Auth 身份验证。
最终用户调用 url,如:http:///a/b?username=foo&password=bar&session=xxx
然后,反向代理将请求代理到 Apache,将凭据作为基本身份验证令牌发送。
最终用户有三个不同的网址:
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 返回给用户,然后他将此会话信息作为请求的一部分发送(在查询字符串中,会话参数中)
为了在后端 tomcat(tomcat1、tomcat2)中维护会话状态,java 反向代理从查询字符串中获取会话并将其作为 JSESSIONID cookie 发送到代理 tomcat。
对于受基本身份验证保护的 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 需要吗?
我很确定我做错了什么,但我已经环顾了很长时间,但我无法让它工作。
非常感激你的帮助。
谢谢