В настоящее время я использую mod_proxy_ajp для загрузки запросов балансировки на несколько серверов Tomcat. Вызывающие абоненты проходят аутентификацию с использованием клиентских сертификатов и ACL. Это работает нормально, звонящие направляются на любой из серверов с одинаковой скоростью. Теперь я хочу предварительно получить и кэшировать данные для каждого пользователя, чтобы каждый сервер Tomcat обслуживал известный набор пользователей. Поэтому я думаю, что было бы хорошо разделить звонящего по алфавиту; Пользователь с именами (CN или DN), начинающимися с A-M, переходит на сервер 1, пользователи с именами, начинающимися с [N-Z], переходят на сервер 2. Но я не знаю, как это сделать.
На данный момент у меня есть:
<Proxy balancer://lb-service>
BalancerMember ajp://svr1:8009 loadfactor=1
BalancerMember ajp://svr2:8009 loadfactor=1
</Proxy>
<Location /lookup>
ProxyPass balancer://lb-service/lookup
</Location>
Я рассматриваю возможность использования mod_rewite для изменения URL-адреса, чтобы включить CN пользователя, но, похоже, я не могу заставить это работать.
Я в значительной степени застрял в использовании apache mod_proxy_ajp и Tomcat для балансировки нагрузки. Я могу изменить службы, в которых запущен Tomcat, для приема различных запросов.
У кого-нибудь есть хороший способ сделать это?
Интересная идея для кеширования! Посмотрим, сможем ли мы заставить его работать ...
У меня есть несколько вариантов: один будет более эффективным, но я понятия не имею, сработает ли он, и другой, менее эффективный, но я уверен, что он будет работать нормально.
Проблема с более эффективным вариантом (и, в более общем смысле, с использованием чего-то вроде сертификата клиента для определения назначения балансировщика нагрузки) заключается в том, что, насколько я знаю, нет никакого способа изменить мнение mod_proxy_balancer о назначении узла после того, как запрос пришел - есть возможно, какой-нибудь творческий хакерский прием, который мог бы сделать это, но я не придумываю никаких лучших идей в голове. Суть в том, что он выполняет перенаправление в то же место, где находится, чтобы иметь cookie для первого запроса, который получает прокси, чтобы получить правильный маршрут - и я не уверен, что это сработает. . Стоит попробовать:
RewriteEngine On
RewriteCond %{ENV:BALANCER_ROUTE_CHANGED} 1
RewriteCond %{SSL:SSL_CLIENT_S_DN} ^[a-m] [NC]
RewriteRule ^(.*)$ /.$1 [R,CO=ROUTEID:route.1:.yourdomain.com]
RewriteCond %{ENV:BALANCER_ROUTE_CHANGED} 1
RewriteCond %{SSL:SSL_CLIENT_S_DN} ^[n-z] [NC]
RewriteRule ^(.*)$ /.$1 [R,CO=ROUTEID:route.2:.yourdomain.com]
<Proxy balancer://lb-service>
BalancerMember ajp://svr1:8009 loadfactor=1 route=1
BalancerMember ajp://svr2:8009 loadfactor=1 route=2
ProxySet stickysession=ROUTEID
</Proxy>
<Location /lookup>
ProxyPass balancer://lb-service/lookup
</Location>
Если это не сработает, то вот план Б; просто каждый раз сопоставляйте DN сертификата клиента. Добавление дополнительных накладных расходов к каждому запросу, но это не должно сильно сказаться на производительности в целом.
<Proxy */lookup>
RewriteEngine On
RewriteCond %{SSL:SSL_CLIENT_S_DN} ^[a-m] [NC]
RewriteRule ^/lookup((?:/.*|))$ ajp://svr1:8009/lookup$1 [P,L]
RewriteCond %{SSL:SSL_CLIENT_S_DN} ^[n-z] [NC]
RewriteRule ^/lookup((?:/.*|))$ ajp://svr2:8009/lookup$1 [P,L]
# This will take care of any other orphan requests (say, those with no client
# cert) - we'll just lump those on server 1; if there's a lot then we can do
# something else to balance randomly (like just leave the current config there)
RewriteRule ^/lookup((?:/.*|))$ ajp://svr1:8009/lookup$1 [P,L]
</Proxy>
У меня есть это соответствие для завершающей косой черты после /lookup
чтобы избежать неприятной уязвимости системы безопасности, из-за которой злоумышленник может проникнуть в вашу внутреннюю сеть - если это не сработает для вашего приложения, мы сможем ее обойти.