高性能Web服务之Httpd负载均衡Tomcat实现Session Sticky及Session Cluster
Httpd负载均衡Tomcat实现Session Sticky及Session Cluster架构如下所示:
实现过程如下:
配置tomcat服务(tomcat1\tomcat2)
(1)安装JDK
# rpm -ivh jdk-7u9-linux-x64.rpm --安装JDK后生成的文件 # cd /usr/java/ ; ll total 4 lrwxrwxrwx 1 root root 16 Sep 27 09:09 default -> /usr/java/latest drwxr-xr-x 10 root root 4096 Sep 27 09:09 jdk1.7.0_09 lrwxrwxrwx 1 root root 21 Sep 27 09:09 latest -> /usr/java/jdk1.7.0_09 --配置JDK环境变量 # vim /etc/profile.d/java.sh export JAVA_HOME=/usr/java/jdk1.7.0_09 export PATH=$PATH:$JAVA_HOME/bin --执行使环境变量生效 # . /etc/profile.d/java.sh --测试如下: # java -version java version "1.7.0_45" --jdk版本 OpenJDK Runtime Environment (rhel-2.4.3.3.el6-x86_64 u45-b15) OpenJDK 64-Bit Server VM (build 24.45-b08, mixed mode)
(2)安装tomcat
--解压tomcat包至/usr/local下 # tar xf apache-tomcat-7.0.72.tar.gz -C /usr/local/ # cd /usr/local/ # ln -sv apache-tomcat-7.0.72 tomcat --配置tomcat环境变量 # vim /etc/profile.d/tomcat.sh export CATALINA_HOME=/usr/local/tomcat export PATH=$PATH:$CATALINA_HOME/bin # . /etc/profile.d/tomcat.sh --测试如下: # catalina.sh version Using CATALINA_BASE: /usr/local/tomcat Using CATALINA_HOME: /usr/local/tomcat Using CATALINA_TMPDIR: /usr/local/tomcat/temp Using JRE_HOME: /usr/java/jdk1.7.0_09 Using CLASSPATH: /usr/local/tomcat/bin/bootstrap.jar:/usr/local/tomcat/bin/tomcat-juli.jar Server version: Apache Tomcat/7.0.67 Server built: Dec 7 2015 13:07:11 UTC Server number: 7.0.72.0 OS Name: Linux OS Version: 2.6.32-431.el6.x86_64 Architecture: amd64 JVM Version: 1.7.0_09-b05 JVM Vendor: Oracle Corporation --为tomcat提供srv启动脚本 # vim /etc/init.d/tomcat #!/bin/sh # Tomcat init script for Linux. # # chkconfig: 2345 96 14 # description: The Apache Tomcat servlet/JSP container. # JAVA_OPTS='-Xms64m -Xmx128m' JAVA_HOME=/usr/java/latest CATALINA_HOME=/usr/local/tomcat export JAVA_HOME CATALINA_HOME case $1 in start) $CATALINA_HOME/bin/catalina.sh start;; stop) $CATALINA_HOME/bin/catalina.sh stop;; restart) $CATALINA_HOME/bin/catalina.sh stop sleep 2 $CATALINA_HOME/bin/catalina.sh start;; *) echo "Usage: `basename $0` {start|stop|restart}" exit 1 ;; esac # chmod +x /etc/init.d/tomcat # chkconfig --add tomcat # service tomcat start --检查tomacat默认监听端口如下所示: # ss -tunlp | grep java tcp LISTEN 0 100 :::8080 :::* users:(("java",19525,42)) tcp LISTEN 0 1 ::ffff:127.0.0.1:8005 :::* users:(("java",19525,47)) tcp LISTEN 0 100 :::8009 :::* users:(("java",19525,43))
(3)配置虚拟主机如下所示(两台tomcat都要配置):
# vim /usr/local/tomcat/conf/server.xml #设置默认虚拟主机为www.samlee.com #第二台tomcatserver的jvmRoute设置为TomcatB <Engine name="Catalina" defaultHost="www.samlee.com" jvmRoute="TomcatA"> #添加虚拟主机: <Host name="www.samlee.com" appBase="/web/webapps/" unpackWARS="true" autoDeploy="true"> <Context path="" docBase="/web/webapps" reloadable="true" /> <Valve className="org.apache.catalina.valves.AccessLogValve" directory="/web/logs" prefix="samlee_access_log." suffix=".txt" pattern="%h %l %u %t "%r" %s %b" /> </Host> #创建虚拟主机目录: # mkdir -pv /web/webapps/{WEB-INF,META-INF,classes,lib}
(4)创建网页文件(两台tomcat都要配置):
tomcatA: # vim /web/webapps/index.jsp <%@ page language="java" %> <html> <head><title>TomcatA</title></head> <body> <h1><font color="red">TomcatA.samlee.com</font></h1> <table align="centre" border="1"> <tr> <td>Session ID</td> <% session.setAttribute("samlee.com","samlee.com"); %> <td><%= session.getId() %></td> </tr> <tr> <td>Created on</td> <td><%= session.getCreationTime() %></td> </tr> </table> </body> </html> tomcatB: # vim /web/webapps/index.jsp <%@ page language="java" %> <html> <head><title>TomcatB</title></head> <body> <h1><font color="blue">TomcatB.samlee.com</font></h1> <table align="centre" border="1"> <tr> <td>Session ID</td> <% session.setAttribute("samlee.com","samlee.com"); %> <td><%= session.getId() %></td> </tr> <tr> <td>Created on</td> <td><%= session.getCreationTime() %></td> </tr> </table> </body> </html>
重启tomcat服务部署:
# service tomcat stop # service tomcat start
访问测试如下:
配置httpd 实现负载均衡反向代理tomcat
配置文件如下所示:
# vim /etc/httpd/conf.d/proxy.conf <Proxy balancer://lbcluster> BalancerMember ajp://192.168.56.11:8009 loadfactor=1 route=TomcatA BalancerMember ajp://192.168.56.12:8009 loadfactor=1 route=TomcatB </Proxy> <VirtualHost *:80> ServerName www.samlee.com ProxyVia on ProxyRequests off ProxyPa***everse / balancer://lbcluster/ ProxyPass / balancer://lbcluster/ </VirtualHost>
重启httpd服务访问测试如下所示:
# service httpd restart
测试如下:
以上我们可以看到反向代理及负载均衡已经生效。
配置httpd 实现session sticky会话绑定
如果tomcat运行着一个动态站点, 那么上面这种byrequest的负载均衡调度算法就有很大问题了, 可能刚登录站点再刷新又回到没有登录的状态了, 所以我们就要实现session sticky, 其实session sticky就是我们之前lvs的sh算法, 和nginx的ip_hash实现的效果
配置文件如下所示:
# vim /etc/httpd/conf.d/proxy.conf Header add Set-Cookie "ROUTEID=.%{BALANCER_WORKER_ROUTE}e; path=/" env=BALANCER_ROUTE_CHANGED <Proxy balancer://lbcluster> BalancerMember ajp://192.168.56.11:8009 loadfactor=1 route=TomcatA BalancerMember ajp://192.168.56.12:8009 loadfactor=1 route=TomcatB ProxySet stickysession=ROUTEID </Proxy> <VirtualHost *:80> ServerName www.samlee.com ProxyVia on ProxyRequests off ProxyPa***everse / balancer://lbcluster/ ProxyPass / balancer://lbcluster/ </VirtualHost>
重启httpd服务访问测试如下所示:
# service httpd restart
测试如下:
如上图所示,显示已经成功将session会话绑定在tomcatA主机上了。
配置tomcat实现session cluster 会话信息共享复制:
*使用session sticky会有很多问题, 如果某台主机宕机了, 那么用户的session就丢失了, 所以我们还可以通过session cluster保存用户会话.
**什么是Session Cluster?? 正常情况下session信息是保存在用户所访问的服务器上,服务器宕机, 用户的session就丢失了, 但是我们可以通过session cluster的方式来实现将用户的session信息保存在后端所有的服务器上, 这样来, 无论用户在访问哪一台服务器,session都不会丢失.
四种常见的session manager
**StandardManager **PersistentManager: 可以将session信息保存在持久存储中 **DeltaManager: 将session信息通过多播的形式共享到其他节点 **BackupManager: 将session信息共享到特定的一个节点上
在配置tomcat前,先将httpd配置的session sticky取消:
构建DeltaManager集群步骤:
1、在各节点的server.xml的engine或host容器添加如上内容;注意修改MemberShip组件中的多播地址address="228.0.0.4",建议修改Receiver中的address为本机能够传递心跳信息的地址;
2、在各节点为使用组播地址添加组播路由,格式:
route add -net $MCAST_ADDRESS netmask 255.255.255.255 dev eth0
3、在相应应用程序的web.xml中添加<distributable\>;
编辑配置tomcat配置文件如下所示(两台tomcat主机都要配置):
下列内容放在<Host />内 <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.1.7" port="45564" frequency="500" dropTime="3000"/> <Receiver className="org.apache.catalina.tribes.transport.nio.NioReceiver" address="192.168.56.12" --这里修改该本机IP地址 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>
配置WEB-INF中的web.xml文件如下:
# cp /usr/local/tomcat/webapps/ROOT/WEB-INF/web.xml /web/webapps/WEB-INF/ # vim /web/webapps/WEB-INF/web.xml #添加下面这一行,在</web-app>内 <distributable/> --复制配置文件web.xml至tomcatA主机上 # scp /web/webapps/WEB-INF/web.xml [email protected]:/web/webapps/WEB-INF/ --复制配置文件server.xml至tomcatA主机上,并按要求修改IP地址及虚拟主机jvmRoute # scp /usr/local/tomcat/conf/server.xml [email protected]:/usr/local/tomcat/conf/
为各tomcat节点添加组播路由地址(两台tomcat主机都要配置):
route add -net 228.0.1.7 netmask 255.255.255.255 dev eth0
重启tomcat服务
# service tomcat stop # service tomcat start
访问测试如下所示:
上图我们看到session会话ID访问后一直没有,证明已经配置会话共享成功了。
转载于:https://blog.51cto.com/gzsamlee/1860175