Apache + Tomcat - проблемы с липкими сеансами и балансировкой нагрузки
Я сталкиваюсь с некоторыми проблемами с Apache mod_proxy_balancer в отношении липких сессий.
Мы разработали успокоительный веб-сервис в Java, работающий на Tomcat. Фактический бэкэнд использует защиту Acegi, с аутентификацией Auth Basic.
Архитектура (извините, что я новый пользователь, я не могу отправлять изображения):
--------------------
|Java Reverse Proxy|
--------------------
|
--------------------
|Apache load balancer|
--------------------
|
--------|--------
| |
-------- --------
|tomcat1| |tomcat2|
-------- --------
У нас есть этот "Обратный прокси Java" для выполнения различных бизнес-задач. Он также выполняет аутентификацию Basic Auth на Tomcat (Tomcat1, Tomcat2).
Конечный пользователь вызывает URL-адреса, такие как: http:///a/b? username = foo & password = bar & session = xxx
Затем обратный прокси-сервер проксирует запрос на Apache, отправляя вместе с учетными данными в качестве основных токенов Auth.
Конечный пользователь имеет три разных 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 возвращается пользователю, а затем он отправляет эту информацию сеанса как часть запроса (в строке запроса, параметре сеанса)
Чтобы поддерживать состояния сеанса в кодах backend (tomcat1, tomcat2), обратный прокси java получает сеанс из строки запроса и отправляет его в проксированные коты в качестве файла cookie JSESSIONID.
Все работает отлично для 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
Как вы можете видеть, хотя файл cookie JSESSIONID одинаковый, Apache отправляет запрос на неправильный tomcat (здесь tomcat1).
Не может ли быть фактом, что URL-адрес службы3 не требует аутентификации Auth Basic, wherease service1 и service2?
Я уверен, что сделал что-то неправильно, но я долго смотрел вокруг, и я не могу заставить его работать.
Ваша помощь очень ценится.
Спасибо
Ответы
Ответ 1
Я не вижу суффикса jvmRoute на вашем JSESSIONID. mod_proxy использует jvmRoute для правильного направления липких сеансов в экземпляры Tomcat. jvmRoute объявляется в конфигурации вашего сервера tomcat (где каждый экземпляр сервера имеет свой собственный уникальный идентификатор jvmRoute.
Ответ 2
Я столкнулся с той же проблемой и решил ее, изменив нижнюю строку -
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
Ответ 3
Может быть, это поможет. Это моя конфигурация на веб-сервере:
<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>
Конфигурация в server.xml сервера tomcat 1:
<Engine name="Catalina" defaultHost="localhost" jvmRoute="tomcat1"}">