目錄
1、環境概述
2、時間同步
3、實現過程
4、測試
5、討論及總結
1、環境概述
測試環境拓撲如下:
clients
|
httpd
/ \
tomcat1 tomcat2
tomcat、httpd的安裝已不再重複,但版本在這裡說明:
httpd服務器(以負載均衡方式工作)
[root@lb conf.d]# cat /etc/issue
CentOS release 6.4 (Final)
Kernel \r on an \m
[root@lb conf.d]# uname -r
2.6.32-358.el6.x86_64
[root@lb conf.d]# ifconfig | grep Bcast:
inet addr:192.168.0.200 Bcast:192.168.0.255 Mask:255.255.255.0
[root@lb conf.d]# rpm -q httpd
httpd-2.2.15-39.el6.centos.x86_64
後端tomcat服務器環境,操作系統版本與httpd服務器相同
[root@master ~]# 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/latest
Using CLASSPATH: /usr/local/tomcat/bin/bootstrap.jar:/usr/local/tomcat/bin/tomcat-juli.jar
Server version: Apache Tomcat/8.0.21
Server built: Mar 23 2015 14:11:21 UTC
Server number: 8.0.21.0
OS Name: Linux
OS Version: 2.6.32-358.el6.x86_64
Architecture: amd64
JVM Version: 1.8.0_45-b14
JVM Vendor: Oracle Corporation
2、時間同步
請參照此博文的相關部份配置 http://zhaochj.blog.51cto.com/368705/1635982
3、實現過程
在之前的博文中已實現了apache以mod_jk和mod_proxy兩種類型實現對後端tomcat進行負載均衡的部署,但都有一個缺陷,在不啟用sticky session時,客戶端訪問前端apache後被調度到後端的tomcat節點,當訪問節點發生改變時此負載均衡系統不能保證用戶session信息不變;如果啟用sticky session,在一定程度上解決了用戶session信息的丟失問題,但是當用戶所訪問的節點宕機時,用戶的session信息依然會丟失,那是否有方法解決這個問題?
當然,常用有兩種方案,方案一:採用節點間session複製技術,當用戶被調度到一tomcat節點時,用戶的session信息會被同步到其他節點,一般採用組播的方式傳遞session信息,只要在同一個組播裡的成員都會有一份session複製器,這樣不管是哪個tomcat節點宕機,其他節點上也有一份接近(如果session信息變化又沒來得及同步就宕機,那其他節點的session就不完整)完整的session信息,對用戶來說是透明的;方案二就是單獨部署session服務器,利用google的MSM(Memcached Session Manager)項目來實現,這個此博文不討論,將在後邊博文中來呈現。
前提:此次環境是在上次博文「
apache以mod_proxy實現負載均衡集群」的基礎上來實現集群的session複製機制。
因tomcat的版本不同,在實現集群session複製時有些細微的區別,所以根據官方文檔來配置,我的環境是tomcat是8.0.21的版本,官方文檔這裡 http://tomcat.apache.org/tomcat-8.0-doc/cluster-howto.html#Bind_session_after_crash_to_failover_node
配置tomcat,實現集群的session複製:
[root@tomcat1 ~]# vim /usr/local/tomcat/conf/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="192.168.0.201"
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.ClusterSessionListener"/>
</Cluster>
註:以上內容定義在Engine容器中,則表示對所有主機均啟動用集群功能。如果定義在某Host容器中,則表示僅對此主機啟用集群功能。此外,需要注意的是,Receiver中的address="auto"一項的值最好改為當前主機集群服務所對應的網絡接口的IP地址。
接下來更改web應用程序根目錄下「WEB-INF」目錄下的web.xml文件,必須添加<distributable/>這個元素,如果web應用程序沒有這個目錄及文件,則可複製默認站點的web.xml文件。
[root@tomcat1 ~]# vim /tomcat/webapps/test/WEB-INF/web.xml
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1"
metadata-complete="true">
<display-name>Welcome to Tomcat</display-name>
<description>
Welcome to Tomcat
</description>
<distributable/>
</web-app>
#在web-app容器中加入<distributable/>元素即可。
到此,tomcat1配置完成,在tomcat2上也作上邊的這些修改後重新啟動tomcat服務,重啟後注意觀察服務器的監聽端口,會有server.xml配置文件中配置的端口出現,如下:
[root@master ~]# netstat -tnlup
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 1100/sshd
tcp 0 0 127.0.0.1:25 0.0.0.0:* LISTEN 1184/master
tcp 0 0 :::8080 :::* LISTEN 3422/java
tcp 0 0 :::22 :::* LISTEN 1100/sshd
tcp 0 0 ::1:25 :::* LISTEN 1184/master
tcp 0 0 ::ffff:192.168.0.201:4000 :::* LISTEN 3422/java
tcp 0 0 ::ffff:127.0.0.1:8005 :::* LISTEN 3422/java
tcp 0 0 :::8009 :::* LISTEN 3422/java
udp 0 0 192.168.0.201:123 0.0.0.0:* 1108/ntpd
udp 0 0 127.0.0.1:123 0.0.0.0:* 1108/ntpd
udp 0 0 0.0.0.0:123 0.0.0.0:* 1108/ntpd
udp 0 0 fe80::20c:29ff:fec6:f77a:123 :::* 1108/ntpd
udp 0 0 ::1:123 :::* 1108/ntpd
udp 0 0 :::123 :::* 1108/ntpd
udp 0 0 :::45564 :::* 3422/java
4、測試
打開瀏覽器訪問前端的httpd監聽的地址,得到的結果如下圖:
看兩次訪問到的頁面,第一次訪問到了tomcat1節點上的測試頁面,第二訪問到了tomcat2上的測試頁面,但兩次訪問的session信息是保持不變的。測試說明兩個節點間的session已完成了複製。
5、討論及總結
官方建議此Clustering/Session Replication技術只能用在小規模的集群環境中,有網友做過測試,當後端的tomcat節點數大於5個時,整個集群的性能不會再上升。
這裡還有一個問題值得討論,在生產環境下實現了session在各節點間的複製,在httpd上的配置中是否要啟用session粘性或綁定呢,即使不啟用綁定session,mod_proxy或mod_jk會根據配置的調度算法來把客戶端的請求分發到後端的tomcat節點上,如果啟用session的綁定功能,那客戶端在一段時間內會被分發到同一個tomcat節點上,如果是以mod_proxy方式實現負載集群時要記得啟用故障轉移選項(nofailover=Off),不然,客戶端之前問題的tomcat節點發生故障,那客戶端將無法實現故障轉移,不過這好像是默認選項。
在集群session複製的負載均衡環境中是否啟用session粘性功能我個人認為需要不斷的監控調度節點、後端的tomcat各節點的負載情況來再做調整。
本文出自 「 專注Linx,與Linux共舞」 博客,請務必保留此出處 http://zhaochj.blog.51cto.com/368705/1650728