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我们都是一样的保持,即实现了负载均衡有实现了会话保持。