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訪問後一直沒有,證明已經配置會話共享成功了。