Apache + Tomcat - проблемы с липкими сессиями и балансировкой нагрузки - PullRequest
14 голосов
/ 22 февраля 2012

У меня возникли некоторые проблемы с Apache mod_proxy_balancer, касающиеся липких сессий.

Мы разработали полноценный веб-сервис на Java, работающий на Tomcat.Фактический бэкэнд использует безопасность Acegi с аутентификацией Basic Auth.

Архитектура (извините, я новый пользователь, я не могу публиковать изображения):

     --------------------
     |Java Reverse Proxy|
     --------------------
            |
     --------------------
     |Apache load balancer|
     --------------------               
            |
    --------|--------
    |               |
--------        --------    
|tomcat1|       |tomcat2|
--------        --------    

У нас есть этот «Java Reverse Proxy» для выполнения различных бизнес-задач.Он также выполняет обычную проверку подлинности на Tomcat (Tomcat1, Tomcat2).

Конечный пользователь вызывает URL-адреса, такие как: http: /// a / b? Username = foo & password = bar & session = xxx

Обратный прокси-сервер затем передает запрос в Apache, отправляя учетные данные как токены Basic 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возвращается пользователю, а затем он отправляет эту информацию о сеансе как часть запроса (в строке запроса, параметр сеанса)

Для сохранения состояний сеансов в бэкэнде tomcats (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 для service3 не требует аутентификации Basic Auth, гдеservice1 и service2 делают?

Я почти уверен, что сделал что-то неправильно, но я долго осматривался и не могу заставить его работать.

Ваша помощь очень ценится.

Спасибо

Ответы [ 3 ]

6 голосов
/ 24 февраля 2012

Я не вижу суффикс jvmRoute на вашем JSESSIONID.mod_proxy использует jvmRoute для правильной маршрутизации липких сессий к вашим экземплярам Tomcat.jvmRoute объявлен в конфигурации вашего сервера Tomcat (где каждый экземпляр сервера имеет свой уникальный идентификатор jvmRoute.

1 голос
/ 16 апреля 2014

Я столкнулся с той же проблемой и решил ее, изменив следующую строку -

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 Reference - http://httpd.apache.org/docs/2.2/mod/mod_proxy_balancer.html

0 голосов
/ 26 сентября 2013

Может быть, это поможет. Это мой конфиг на веб-сервере:

<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 Server 1:

<Engine name="Catalina" defaultHost="localhost" jvmRoute="tomcat1"}">
...