Я изо всех сил пытался заставить балансировку нагрузки и кластеризацию работать с использованием этой комбинации:
Некоторые ссылки, которые я прочитал:
Это моя конфигурация:
httpd.conf
# Required Modules
LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_ajp_module modules/mod_proxy_ajp.so
LoadModule proxy_balancer_module modules/mod_proxy_balancer.so
LoadModule status_module modules/mod_status.so
# Reverse Proxy
<Proxy balancer://mybalancer>
BalancerMember ajp://localhost:8301 route=s1
BalancerMember ajp://localhost:8302 route=s2
BalancerMember ajp://localhost:8303 route=s3
</Proxy>
ProxyPass / balancer://mybalancer/ stickysession=JSESSIONID|jsessionid
# Forward Proxy
ProxyRequests Off
<Proxy *>
Order deny,allow
Deny from none
Allow from localhost
</Proxy>
# Balancer-manager, for monitoring
<Location /balancer-manager>
SetHandler balancer-manager
Order deny,allow
Deny from none
Allow from localhost
</Location>
server.xml для каждого кота (разница только в номере порта)
<Server port="8001" shutdown="SHUTDOWN">
<Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" />
<Listener className="org.apache.catalina.core.JasperListener" />
<Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" />
<Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" />
<Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener" />
<GlobalNamingResources>
<Resource name="UserDatabase" auth="Container"
type="org.apache.catalina.UserDatabase" description="User database that can be updated and saved"
factory="org.apache.catalina.users.MemoryUserDatabaseFactory" pathname="conf/tomcat-users.xml" />
</GlobalNamingResources>
<Service name="Catalina">
<Connector port="8101" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8201" />
<Connector port="8301" protocol="AJP/1.3" redirectPort="8201" />
<Engine name="Catalina" defaultHost="localhost" jvmRoute="s1">
<Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster" channelSendOptions="8">
<Manager className="org.apache.catalina.ha.session.DeltaManager" expireSessionsOnShutdown="false"
notifyListenersOnReplication="true" />
<Channel className="org.apache.catalina.tribes.group.GroupChannel">
<Membership className="org.apache.catalina.tribes.membership.McastService"
address="228.0.0.4" port="45564" frequency="500" dropTime="3000" />
<Sender className="org.apache.catalina.tribes.transport.ReplicationTransmitter">
<Transport className="org.apache.catalina.tribes.transport.nio.PooledParallelSender" />
</Sender>
<Receiver className="org.apache.catalina.tribes.transport.nio.NioReceiver"
address="auto" port="4000" autoBind="100" selectorTimeout="5000" maxThreads="6" />
<Interceptor className="org.apache.catalina.tribes.group.interceptors.TcpFailureDetector" />
<Interceptor className="org.apache.catalina.tribes.group.interceptors.MessageDispatch15Interceptor" />
</Channel>
<Valve className="org.apache.catalina.ha.tcp.ReplicationValve" filter="" />
<Valve className="org.apache.catalina.ha.session.JvmRouteBinderValve" />
<ClusterListener className="org.apache.catalina.ha.session.JvmRouteSessionIDBinderListener" />
<ClusterListener className="org.apache.catalina.ha.session.ClusterSessionListener" />
</Cluster>
<Realm className="org.apache.catalina.realm.LockOutRealm">
<Realm className="org.apache.catalina.realm.UserDatabaseRealm" resourceName="UserDatabase" />
</Realm>
<Host name="localhost" appBase="webapps" unpackWARs="true" autoDeploy="true">
<Valve className="org.apache.catalina.valves.AccessLogValve"
directory="logs" prefix="localhost_access_log." suffix=".txt"
pattern="%h %l %u %t "%r" %s %b" />
</Host>
</Engine>
</Service>
</Server>
нумерация портов (убедитесь, что ни один из экземпляров не использует один и тот же порт, если они развернуты на одном сервере)
Пружинный контроллер
@Controller
@RequestMapping("/login")
public class LoginController {
@RequestMapping(method=RequestMethod.GET)
public String show(@ModelAttribute("user") User user, HttpServletRequest request) {
user.setUsername("YUSUF");
HttpSession session = request.getSession();
Integer tambah = (Integer) session.getAttribute("tambah");
if(tambah == null) tambah = new Integer(1);
else tambah = new Integer(tambah.intValue() + 1);
session.setAttribute("tambah", tambah);
return "login";
}
}
login.jsp
<div class="mainFooter">
Tambah = ${sessionScope.tambah}
<br>
ID = ${pageContext.session.id}
</div>
Пока что часть балансировки нагрузки работает, а репликация сеанса - нет.
В основном я хочу, чтобы если я продолжал нажимать кнопку «Обновить» на странице входа в систему, переменная «tambah» будет увеличиваться и сохраняться в сеансе. И если текущий узел tomcat не работает, сеанс будет реплицирован на следующий узел tomcat, и данные не исчезнут. Но вот что происходит:
Экран входа в систему:
Tambah = 39
ID = C1D59C8CA5D10EB98C1DE08AC618204D.s1
Я отключаю tomcat1 и продолжаю работу tomcat2 и tomcat3, вот экран входа в систему:
Tambah = 1
ID = A83KJFO38FK30FJDL40FLREI39FKDKGD.s2
Кажется, что аварийное переключение не работает, сеанс не реплицируется, и приложение создало новый сеанс. Может ли кто-нибудь помочь мне указать правильное направление?
Спасибо
РЕДАКТИРОВАТЬ: Я решил вопрос, благодаря @Shane Madden, это изменения, которые я внес:
<Receiver className="org.apache.catalina.tribes.transport.nio.NioReceiver"
address="auto" port="4000" autoBind="100" selectorTimeout="5000" maxThreads="6" />
Для каждого Tomcat порт приемника tcp должен быть разным (если он работает на одном сервере), например, используйте 4001, 4002, 4003 и т. Д.
Благодаря комментариям @Shane Madden я перечитал документы кластера tomcat в http://tomcat.apache.org/tomcat-7.0-doc/cluster-howto.html, особенно в этой части -> «Если ваши экземпляры Tomcat работают на одном компьютере, убедитесь, что атрибут tcpListenPort уникален для каждого экземпляра, в большинстве случаев Tomcat достаточно умен, чтобы решить эту проблему самостоятельно, автоматически определяя доступные порты в диапазоне 4000-4100 ".
Изменения, которые я внес, есть в каждом экземпляре Tomcat server.xml, я проверяю, что каждый порт отличается (например, 4001, 4002, 4003):
<Receiver className="org.apache.catalina.tribes.transport.nio.NioReceiver"
address="auto" port="4001" autoBind="100"
selectorTimeout="5000" maxThreads="6" />
И вуаля! балансировка нагрузки и кластеризация работают (конечно с самой базовой конфигурацией). Я надеюсь, что этот пост поможет другим в начальных настройках.
У меня похожий программный стек (apache 2.2.15 и tomcat 7.0.65), но все Linux и я столкнулись со следующей проблемой со страницей состояния балансировщика: вместо того, чтобы попасть на страницу состояния, директива ProxyPass
ProxyPass / balancer://mybalancer/ stickysession=JSESSIONID|jsessionid
перенаправлял запрос / balancer-manager одному из котов (и, таким образом, получал страницу с ошибкой tomvat). Я решил проблему, установив для ProxyPass что-то более ограничительное, чем просто /
ProxyPass /myapp balancer://mybalancer/myapp stickysession=JSESSIONID|jsessionid
Не уверены, что это правильный способ сделать это?