httpd版本:2.4.6
tomcat版本:7.0.69
dedis版本:3.2.3
操作系统版本:CentOS Linux release 7.3.1611
拓扑结构:
tomcat-A/192.168.1.106
客户端------>httpd反向代理 -------> ----- > redis会话保持服务器
192.168.1.101 tomcat-B/192.168.1.107 192.168.1.100
httpd反向代理:
安装httpd服务
yum -y install httpd
httpd实现反向代理需要三个modules的支持:
mod_proxy.so mod_proxy_http.so mod_proxy_balancer.so
编辑proxy配置
cat /etc/httpd/conf.d/tomcat-proxy.conf <proxy balancer://tcsrvs> balancermember http://192.168.1.106:8080 balancermember http://192.168.1.107:8080 proxyset lbmethod=byrequests #调度方式,根据请求调度,类似于轮询 </proxy> <virtualhost *:80> servername lb.tomcat.com proxyvia on proxyrequests off proxypreservehost on <proxy *> require all granted </proxy> proxypass / balancer://tcsrvs/ proxypassreverse / balancer://tcsrvs/ <location /> require all granted </location> </virtualhost>
tomcat服务器配置:
安装对应的软件包
java-1.8.0-openjdk tomcat tomcat-lib tomcat-admin-webapps tomcat-webapps tomcat-docs-webapp
准备测试文件
mkdir /usr/share/tomcat/webapps/test/ tomcat-A: cat /usr/share/tomcat/webapps/test/index.jsp <%@ page language="java" %> <html> <head><title>TomcatA</title></head> <body> <h1><font color="blue">TomcatA.com</font></h1> <table align="centre" border="1"> <tr> <td>Session ID</td> <% session.setAttribute("tomcatA.com","tomcatA.com"); %> <td><%= session.getId() %></td> </tr> <tr> <td>Created on</td> <td><%= session.getCreationTime() %></td> </tr> </table> </body> </html> tomcat-B: cat /usr/share/tomcat/webapps/test/index.jsp <%@ page language="java" %> <html> <head><title>TomcatB</title></head> <body> <h1><font color="red">TomcatB.com</font></h1> <table align="centre" border="1"> <tr> <td>Session ID</td> <% session.setAttribute("tomcatB.com","tomcatB.com"); %> <td><%= session.getId() %></td> </tr> <tr> <td>Created on</td> <td><%= session.getCreationTime() %></td> </tr> </table> </body> </html>
然后启动tomcat服务
systemctl start tomcat.service
此时在浏览器测试http://192.168.1.101/test/
以上只是完成了httpd调度后端tomcat主机的需求
当客户端访问时,不希望会话信息改变,试想一下,你在电商网站下了单了,然后刷新页面调度器把你的请求调度到另一台机器上,下的单没了,你作何感受?所以,为了避免这种现象的发生,我们通过设置cookie信息,来绑定会话
httpd服务器配置:
cat tomcat-proxy.conf header add set-cookie "ROUTEID=.%{BALANCER_WORKER_ROUTE}e; path=/" env=BALANCER_ROUTE_CHANGED #设置cookie信息 <proxy balancer://tcsrvs> balancermember http://192.168.1.106:8080 route=tomcatA loadfactor=1 balancermember http://192.168.1.107:8080 route=tomcatB loadfactor=1 proxyset lbmethod=byrequests proxyset stickysession=ROUTEID #基于会话粘性来设置cookie </proxy> #route与后端tomcat的jvmRoute对应 <virtualhost *:80> servername lb.tomcat.com proxyvia on proxyrequests off proxypreservehost on <proxy *> require all granted </proxy> proxypass / balancer://tcsrvs/ proxypassreverse / balancer://tcsrvs/ <location /> require all granted </location> </virtualhost>
tomcat主机配置:
vim server.xml <Engine name="Catalina" defaultHost="localhost" jvmRoute="tomcatA"> #修改tomcat主机,jvmRoute是支持负载均衡的
在tomcatB主机也要做类似的修改
完成上述内容就能够实现基于cookie的会话粘性了,在浏览器测试http://192.168.1.101/test/就只会调到同一台主机,当此主机故障会调度到另一台主机
上述基于cookie的会话粘性存在一个问题,即客户端基于cookie访问后端服务器A,如果A主机故障,httpd会重新调度到B主机上,但是B上没有之前的会话信息,所以客户端浏览记录、下单情况等信息就消失了。
可以使用tomcat集群加单独的缓存服务器redis解决上述问题,tomcat集群解决主机单点故障问题,将会话信息单独存放在缓存服务器上而不是tomcat主机
,不过redis为了避免单点问题也要做高可用,这里我们只要能实现会话缓存功能即可。只有高可用大家有兴趣可以自己研究
配置session server的话就不用cookie信息,把httpd配置中的cookie配置删除
vim tomcat-proxy.conf header add set-cookie "ROUTEID=.%{BALANCER_WORKER_ROUTE}e; path=/" env=BALANCER_ROUTE_CHANGED proxyset stickysession=ROUTEID #将上述两行删掉或者注释,然后重启服务
tomcat主机配置集群:
cat server.xml #在Engine字段下配置下述内容 <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"/> <Receiver className="org.apache.catalina.tribes.transport.nio.NioReceiver" address="auto" port="4000" autoBind="100" selectorTimeout="5000" maxThreads="6"/> <Sender className="org.apache.catalina.tribes.transport.ReplicationTransmitter"> <Transport className="org.apache.catalina.tribes.transport.nio.PooledParallelSender"/> </Sender> <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"/> <Deployer className="org.apache.catalina.ha.deploy.FarmWarDeployer" tempDir="/tmp/war-temp/" deployDir="/tmp/war-deploy/" watchDir="/tmp/war-listen/" watchEnabled="false"/> <ClusterListener className="org.apache.catalina.ha.session.JvmRouteSessionIDBinderListener" /> <ClusterListener className="org.apache.catalina.ha.session.ClusterSessionListener" /> </Cluster>
以上内容很多,可以直接复制,不用做任何修改,两台主机都要配置
参考连接http://tomcat.apache.org/tomcat-7.0-doc/cluster-howto.html
注意官网模板配置中有两处错误:
<ClusterListener className="org.apache.catalina.ha.session.JvmRouteSessionIDBinderListener" /> <ClusterListener className="org.apache.catalina.ha.session.ClusterSessionListener" /> #官网中此处末尾都没有加结束符 /
然后修改web.xml
cat web.cml <distributable/> #此处指明tomcat的分布式集群
安装redis,并设置
yum -y install redis vim /etc/redis.conf bind 0.0.0.0 #指定监听所有地址,默认监听端口是tcp6379
然后启动redis服务
接着配置tomcat主机,本处以其中一台为例,另一台也要按此方式配置
cat context.xml #编辑如下内容 <Valve className="com.orangefunction.tomcat.redissessions.RedisSessionHandlerValve" /> <Manager className="com.orangefunction.tomcat.redissessions.RedisSessionManager" host="192.168.1.100" port="6379" database="0" maxInactiveInterval="60" /> #192.168.1.100是redis的地址
准备jar包,三个jar包,其下载地址如下
https://github.com/izerui/tomcat-redis-session-manager.git
然后将这三个jar包,放到tomcat的库目录中,即/usr/share/tomcat/lib/
重启tomcat服务
此时打开浏览器测试http://192.168.1.101/test/,会发现sessionID不变,但调度的后端主机改变了
总结:
redis只修改监听地址即可,其他不用修改任何配置;
httpd只是启动反代的作用,关键是配置对后端主机的调度;
tomcat集群需修改server.xml和web.xml文件,配合redis缓存还需配置context.xml和准备jar包
结束
httpd反代 + tomcat cluster + redis会话保持
原文地址:http://blog.51cto.com/panpangao/2046129