tomcat cluster
Tomcat很重要,当然也少不了它的集群构造,当然我们首先需要关注的是负载均衡集群,而在一个负载集群中会话保持是一个必须考虑的问题,而会话的保持我们也有许多种方法来实现。
cluster session
- session sticky
 source ip,cookie,hash Header
 实现的方法:
- nginx:hash ip_hash
- haproxy: source cookie hdr
- lvs: SH
- httpd: ROUTID
- session cluster
- tomcat delta manager
- tomcat session cluster
- session server
 memcached redis
 实现方法:
- memcached-session-manager
httpd+tomcat负载均衡集群
(1)第一种方式
apache
- mod_proxy
- mod_proxy_http
- mod_proxy_balancer
 tomcat
- http connector
实现负载均衡:
| 1 | <proxy balancer://tserver> | 
| 2 |         BalancerMember http://10.211.55.43:8080 loadfactor=1  | 
| 3 |         BalancerMember http://10.211.55.39:8080 loadfactor=1  | 
| 4 |         ProxySet lbmethod=bybusyness | 
| 5 | </proxy> | 
| 6 | |
| 7 | <VirtualHost *:80> | 
| 8 |         ServerName www.jusene.com | 
| 9 |         ProxyVia On | 
| 10 |         ProxyRequests Off | 
| 11 |         ProxyPreserveHost On | 
| 12 |         <Proxy *> | 
| 13 |                 Require all granted | 
| 14 |         </Proxy> | 
| 15 |         ProxyPass / balancer://tserver/ | 
| 16 |         ProxyPassReverse / balancer://tserver/ | 
| 17 |         <Location /> | 
| 18 |                 Require all granted | 
| 19 |         </Location> | 
| 20 | </VirtualHost> | 
实现会话保持:
| 1 | Header add Set-Cookie "ROUTEID=.%{BALANCER_WORKER_ROUTE}e; path=/" env=BALANCER_ROUTE_CHANGED | 
| 2 | <proxy balancer://tserver> | 
| 3 |         BalancerMember http://10.211.55.43:8080  route=TomcatA  loadfactor=1 | 
| 4 |         BalancerMember http://10.211.55.39:8080  route=TomcatB  loadfactor=2 | 
| 5 |         ProxySet lbmethod=bybusyness | 
| 6 |         ProxySet stickysession=ROUTEID | 
| 7 | </proxy> | 
| 8 | |
| 9 | <VirtualHost *:80> | 
| 10 |         ServerName www.jusene.com | 
| 11 |         ProxyVia On | 
| 12 |         ProxyRequests Off | 
| 13 |         ProxyPreserveHost On | 
| 14 |         <Proxy *> | 
| 15 |                 Require all granted | 
| 16 |         </Proxy> | 
| 17 |         ProxyPass / balancer://tserver/ | 
| 18 |         ProxyPassReverse / balancer://tserver/ | 
| 19 |         <Location /> | 
| 20 |                 Require all granted | 
| 21 |         </Location> | 
| 22 | </VirtualHost> | 
启用管理接口:
| 1 | <Location /balancer> | 
| 2 |                 SetHandler balancer-manager | 
| 3 |                 ProxyPass ! | 
| 4 |                 Require ip 10.211.55.24 | 
| 5 |                 Require all deny | 
| 6 | </Location> | 
(2)第二种方式
apache
- mod_proxy
- mod_proxy_ajp
- mod_proxy_balancer
 tomcat
- ajp connector
实现负载均衡:
| 1 | <proxy balancer://tserver> | 
| 2 |         BalancerMember ajp://10.211.55.43:8009 loadfactor=1  | 
| 3 |         BalancerMember ajp://10.211.55.39:8009 loadfactor=1  | 
| 4 |         ProxySet lbmethod=bybusyness | 
| 5 | </proxy> | 
| 6 | |
| 7 | <VirtualHost *:80> | 
| 8 |         ServerName www.jusene.com | 
| 9 |         ProxyVia On | 
| 10 |         ProxyRequests Off | 
| 11 |         ProxyPreserveHost On | 
| 12 |         <Proxy *> | 
| 13 |                 Require all granted | 
| 14 |         </Proxy> | 
| 15 |         ProxyPass / balancer://tserver/ | 
| 16 |         ProxyPassReverse / balancer://tserver/ | 
| 17 |         <Location /> | 
| 18 |                 Require all granted | 
| 19 |         </Location> | 
| 20 | </VirtualHost> | 
实现会话保持:
| 1 | Header add Set-Cookie "ROUTEID=.%{BALANCER_WORKER_ROUTE}e; path=/" env=BALANCER_ROUTE_CHANGED | 
| 2 | <proxy balancer://tserver> | 
| 3 |         BalancerMember ajp://10.211.55.43:8009  route=TomcatA  loadfactor=1 | 
| 4 |         BalancerMember ajp://10.211.55.39:8009  route=TomcatB  loadfactor=2 | 
| 5 |         ProxySet lbmethod=bybusyness | 
| 6 |         ProxySet stickysession=ROUTEID | 
| 7 | </proxy> | 
| 8 | |
| 9 | <VirtualHost *:80> | 
| 10 |         ServerName www.jusene.com | 
| 11 |         ProxyVia On | 
| 12 |         ProxyRequests Off | 
| 13 |         ProxyPreserveHost On | 
| 14 |         <Proxy *> | 
| 15 |                 Require all granted | 
| 16 |         </Proxy> | 
| 17 |         ProxyPass / balancer://tserver/ | 
| 18 |         ProxyPassReverse / balancer://tserver/ | 
| 19 |         <Location /> | 
| 20 |                 Require all granted | 
| 21 |         </Location> | 
| 22 | </VirtualHost> | 
(3)第三种方式
apache
- mod_jk
 tomcat
- ajp connector
mod_jk的下载地址:http://mirror.bit.edu.cn/apache/tomcat/tomcat-connectors/jk/tomcat-connectors-1.2.42-src.tar.gz
| 1 | ~]# tar xf tomcat-connectors-1.2.42-src.tar.gz | 
| 2 | ~]# cd tomcat-connectors-1.2.42-src | 
| 3 | ~]# cd native | 
| 4 | ~]# ./configure --with-apxs=/usr/bin/apxs | 
| 5 | ~]# make && make install | 
反向代理实现:
| 1 | LoadModule jk_module modules/mod_jk.so | 
| 2 | |
| 3 | JkWorkersFile /etc/httpd/conf.d/workers.properties | 
| 4 | JkLogFile logs/mod_jk.log | 
| 5 | JkLogLevel debug | 
| 6 | JkMount /* TomcatA | 
| 7 | JkMount /jk_status Stat | 
| 1 | ~]# cat /etc/httpd/conf.d/workers.properties | 
| 2 | worker.list=TomcatA,Stat | 
| 3 | worker.TomcatA.host=10.211.55.39 | 
| 4 | worker.TomcatA.port=8009 | 
| 5 | worker.TomcatA.type=ajp13 | 
| 6 | worker.Stat.type=status | 
负载均衡的实现:
| 1 | LoadModule jk_module modules/mod_jk.so | 
| 2 | |
| 3 | JkWorkersFile /etc/httpd/conf.d/workers.properties | 
| 4 | JkLogFile logs/mod_jk.log | 
| 5 | JkLogLevel debug | 
| 6 | JkMount /* tcserver | 
| 7 | JkMount /jk_status Stat | 
| 1 | worker.list=tcserver,Stat | 
| 2 | worker.TomcatA.host=10.211.55.39 | 
| 3 | worker.TomcatA.port=8009 | 
| 4 | worker.TomcatA.type=ajp13 | 
| 5 | worker.TomcatA.lbfactor=1 | 
| 6 | worker.TomcatB.host=10.211.55.43 | 
| 7 | worker.TomcatB.port=8009 | 
| 8 | worker.TomcatB.type=ajp13 | 
| 9 | worker.TomcatB.lbfactor=2 | 
| 10 | worker.tcserver.type=lb | 
| 11 | worker.tcserver.balance_workers=TomcatA,TomcatB | 
| 12 | worker.Stat.type=status | 
会话保持:
| 1 | LoadModule jk_module modules/mod_jk.so | 
| 2 | |
| 3 | JkWorkersFile /etc/httpd/conf.d/workers.properties | 
| 4 | JkLogFile logs/mod_jk.log | 
| 5 | JkLogLevel debug | 
| 6 | JkMount /* tcserver | 
| 7 | JkMount /jk_status Stat | 
| 1 | worker.list=tcserver,Stat | 
| 2 | worker.TomcatA.host=10.211.55.39 | 
| 3 | worker.TomcatA.port=8009 | 
| 4 | worker.TomcatA.type=ajp13 | 
| 5 | worker.TomcatA.lbfactor=1 | 
| 6 | worker.TomcatB.host=10.211.55.43 | 
| 7 | worker.TomcatB.port=8009 | 
| 8 | worker.TomcatB.type=ajp13 | 
| 9 | worker.TomcatB.lbfactor=2 | 
| 10 | worker.tcserver.type=lb | 
| 11 | worker.tcserver.balance_workers=TomcatA,TomcatB | 
| 12 | worker.tcserver.sticky_session=1 | 
| 13 | worker.Stat.type=status | 
这个还需要在每个tomcat的配置文件server.xml中engine中jvmRoute与worker的名称相同
Tomcat Session Replication Cluster
session测试页:
| 1 | <%@ page language="java" %> | 
| 2 | <html> | 
| 3 |  <head><title>TomcatB</title></head> | 
| 4 |  <body> | 
| 5 |  <h1><font color="blue">TomcatB </h1> | 
| 6 |  <table align="centre" border="1"> | 
| 7 |   <tr> | 
| 8 |   <td>Session ID</td> | 
| 9 |  <% session.setAttribute("abc","abc"); %> | 
| 10 |   <td><%= session.getId() %></td> | 
| 11 |   </tr> | 
| 12 |   <tr> | 
| 13 |   <td>Created on</td> | 
| 14 |   <td><%= session.getCreationTime() %></td> | 
| 15 |   </tr> | 
| 16 |  </table> | 
| 17 |  </body> | 
| 18 | </html> | 
根据需要自行修改成不同
负载均衡配置:
| 1 | <proxy balancer://tserver> | 
| 2 |         BalancerMember http://10.211.55.43:8080 loadfactor=1  | 
| 3 |         BalancerMember http://10.211.55.39:8080 loadfactor=1  | 
| 4 |         ProxySet lbmethod=byrequests | 
| 5 | </proxy> | 
| 6 | |
| 7 | <VirtualHost *:80> | 
| 8 |         ServerName www.jusene.com | 
| 9 |         ProxyVia On | 
| 10 |         ProxyRequests Off | 
| 11 |         ProxyPreserveHost On | 
| 12 |         <Proxy *> | 
| 13 |                 Require all granted | 
| 14 |         </Proxy> | 
| 15 |         ProxyPass / balancer://tserver/ | 
| 16 |         ProxyPassReverse / balancer://tserver/ | 
| 17 |         <Location /> | 
| 18 |                 Require all granted | 
| 19 |         </Location> | 
| 20 | </VirtualHost> | 
(1)配置启用集群
TomcatA
| 1 | ~]# vim /etc/tomcat/server.xml | 
| 2 | ... | 
| 3 | <Host name="www.jusene.com"  appBase="webapps" | 
| 4 |             unpackWARs="true" autoDeploy="true"> | 
| 5 |             <Context path="/" docBase="/usr/share/tomcat/webapps/myapp" reloadable="true"> | 
| 6 |             <Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster" | 
| 7 |                  channelSendOptions="8"> | 
| 8 | |
| 9 |           <Manager className="org.apache.catalina.ha.session.DeltaManager" | 
| 10 |                    expireSessionsOnShutdown="false" | 
| 11 |                    notifyListenersOnReplication="true"/> | 
| 12 | |
| 13 |           <Channel className="org.apache.catalina.tribes.group.GroupChannel"> | 
| 14 |             <Membership className="org.apache.catalina.tribes.membership.McastService" | 
| 15 |                         address="228.0.0.4"      #集群成员通信组播地址 | 
| 16 |                         port="45564"			 #心跳端口 | 
| 17 |                         frequency="500"          #每隔500ms检查一次 | 
| 18 |                         dropTime="3000"/>        #3000ms检测未成功剔除集群 | 
| 19 |             <Receiver className="org.apache.catalina.tribes.transport.nio.NioReceiver" | 
| 20 |                       address="auto"             #session通信地址,为外网可通信端口 | 
| 21 |                       port="4000"                #session通信端口 | 
| 22 |                       autoBind="100" | 
| 23 |                       selectorTimeout="5000" | 
| 24 |                       maxThreads="6"/> | 
| 25 | |
| 26 |             <Sender className="org.apache.catalina.tribes.transport.ReplicationTransmitter"> | 
| 27 |               <Transport className="org.apache.catalina.tribes.transport.nio.PooledParallelSender"/> | 
| 28 |             </Sender> | 
| 29 |             <Interceptor className="org.apache.catalina.tribes.group.interceptors.TcpFailureDetector"/> | 
| 30 |             <Interceptor className="org.apache.catalina.tribes.group.interceptors.MessageDispatch15Interceptor"/> | 
| 31 |           </Channel> | 
| 32 | |
| 33 |           <Valve className="org.apache.catalina.ha.tcp.ReplicationValve" | 
| 34 |                  filter=""/> | 
| 35 |           <Valve className="org.apache.catalina.ha.session.JvmRouteBinderValve"/> | 
| 36 | |
| 37 |           <Deployer className="org.apache.catalina.ha.deploy.FarmWarDeployer" | 
| 38 |                     tempDir="/tmp/war-temp/" | 
| 39 |                     deployDir="/tmp/war-deploy/" | 
| 40 |                     watchDir="/tmp/war-listen/" | 
| 41 |                     watchEnabled="false"/> | 
| 42 | |
| 43 |           <ClusterListener className="org.apache.catalina.ha.session.JvmRouteSessionIDBinderListener"/> | 
| 44 |           <ClusterListener className="org.apache.catalina.ha.session.ClusterSessionListener"/> | 
| 45 |         </Cluster> | 
| 46 | ~]# scp server.xml node2:/etc/tomcat/server.xml | 
| 47 | ~]# cp web.xml /usr/share/tomcat/webapps/myapp/WEB-INF | 
| 48 | ~]# cd /usr/share/tomcat/webapps/myapp/WEB-INF | 
| 49 | ~]# cat web.xml | 
| 50 | ... | 
| 51 | |
| 52 | <distributable/> | 
| 53 | ~]# scp web.xml node2:/usr/share/tomcat/webapps/myapp/WEB-INF | 
| 54 | ~]# systemctl start tomcat;ssh node2 'systemctl start tomcat' | 
(2)配置webapps
编辑WEB-INF/web.xml,添加<distributable/>
(3)启动tomcat
session server
memcached-session-manager项目地址:http://code.google.com/p/memcached-session-manager/
下载如下jar文件至各tomcat节点的tomcat安装目录下的lib目录中,其中的${version}要换成你所需要的版本号,tc${6,7,8}要换成与tomcat版本相同的版本号。
memcached-session-manager-${version}.jar
memcached-session-manager-tc${6,7,8}-${version}.jar
spymemcached-${version}.jar
msm-javolution-serializer-${version}.jar
javolution-${version}.jar
负载均衡配置:
| 1 | <proxy banalcer://tcserver> | 
| 2 | 	BalancerMember http://10.211.55.43:8080 loadfactor=1 | 
| 3 | 	BalancerMember http://10.211.55.39:8080 loadfactor=1 | 
| 4 | 	ProxySet lbmethod=byrequests | 
| 5 | </proxy> | 
| 6 | |
| 7 | <VirtualHost *:80> | 
| 8 | 	ServerName www.jusene.com | 
| 9 | 	ProxyVia On | 
| 10 | 	ProxyRequests Off | 
| 11 | 	ProxyPreserveHost On | 
| 12 | 	<Proxy *> | 
| 13 | 		Require all granted | 
| 14 | 	</Proxy> | 
| 15 | 	ProxyPass / balancer://tserver/ | 
| 16 |     ProxyPassReverse / balancer://tserver/ | 
| 17 |     <Location /> | 
| 18 |         Require all granted | 
| 19 |     </Location> | 
| 20 | </VirtualHost> | 
TomcatA:
| 1 | ~]# yum install -y memcached | 
| 2 | ~]# systemctl start memcached | 
| 3 | ~]# vim /etc/tomcat/server.xml | 
| 4 | .... | 
| 5 | <Host name="localhost"  appBase="webapps" | 
| 6 |             unpackWARs="true" autoDeploy="true"> | 
| 7 |         <Context path="/" docBase="/usr/share/tomcat/webapps/myapp" reloadable="true"> | 
| 8 |               <Manager className="de.javakaffee.web.msm.MemcachedBackupSessionManager" | 
| 9 |                 memcachedNodes="n1:10.211.55.43:11211,n2:10.211.55.39:11211" | 
| 10 |                 failoverNodes="n1" | 
| 11 |                 requestUriIgnorePattern=".*\.(ico|png|gif|jpg|css|js)$" | 
| 12 |                 transcoderFactoryClass="de.javakaffee.web.msm.serializer.javolution.JavolutionTranscoderFactory" | 
| 13 |               /> | 
| 14 |              </Context> | 
| 15 | ... | 
| 16 | ~]# systemctl start tomcat | 
| 17 | ~]# cat /usr/share/tomcat/webapps/myapp/index.jsp | 
| 18 | <%@ page language="java" %> | 
| 19 | <html> | 
| 20 |  <head><title>TomcatA</title></head> | 
| 21 |  <body> | 
| 22 |  <h1><font color="blue">TomcatA </h1> | 
| 23 |  <table align="centre" border="1"> | 
| 24 |   <tr> | 
| 25 |   <td>Session ID</td> | 
| 26 |  <% session.setAttribute("abc","abc"); %> | 
| 27 |   <td><%= session.getId() %></td> | 
| 28 |   </tr> | 
| 29 |   <tr> | 
| 30 |   <td>Created on</td> | 
| 31 |   <td><%= session.getCreationTime() %></td> | 
| 32 |   </tr> | 
| 33 |  </table> | 
| 34 |  </body> | 
| 35 | </html> | 
TomcatB:
| 1 | ~]# yum install -y memcached | 
| 2 | ~]# systemctl start memcached | 
| 3 | ~]# vim /etc/tomcat/server.xml | 
| 4 | <Host name="localhost"  appBase="webapps" | 
| 5 |             unpackWARs="true" autoDeploy="true"> | 
| 6 |         <Context path="/" docBase="/usr/share/tomcat/webapps/myapp" reloadable="true"> | 
| 7 |               <Manager className="de.javakaffee.web.msm.MemcachedBackupSessionManager" | 
| 8 |                 memcachedNodes="n1:10.211.55.43:11211,n2:10.211.55.39:11211" | 
| 9 |                 failoverNodes="n1" | 
| 10 |                 requestUriIgnorePattern=".*\.(ico|png|gif|jpg|css|js)$" | 
| 11 |                 transcoderFactoryClass="de.javakaffee.web.msm.serializer.javolution.JavolutionTranscoderFactory" | 
| 12 |               /> | 
| 13 |              </Context> | 
| 14 | ~]# systemctl start tomcat | 
| 15 | ~]# cat /usr/share/tomcat/webapps/myapp/index.jsp | 
| 16 | <%@ page language="java" %> | 
| 17 | <html> | 
| 18 |  <head><title>TomcatB</title></head> | 
| 19 |  <body> | 
| 20 |  <h1><font color="blue">TomcatB </h1> | 
| 21 |  <table align="centre" border="1"> | 
| 22 |   <tr> | 
| 23 |   <td>Session ID</td> | 
| 24 |  <% session.setAttribute("abc","abc"); %> | 
| 25 |   <td><%= session.getId() %></td> | 
| 26 |   </tr> | 
| 27 |   <tr> | 
| 28 |   <td>Created on</td> | 
| 29 |   <td><%= session.getCreationTime() %></td> | 
| 30 |   </tr> | 
| 31 |  </table> | 
| 32 |  </body> | 
| 33 | </html> | 
结果:

前端负载均衡无论分发到那台机器上,会话id我们都是一样的保持,即实现了负载均衡有实现了会话保持。