什么是會(huì)話保持
會(huì)話是指一個(gè)終端用戶與交互系統(tǒng)進(jìn)行通訊的過(guò)程,比如從輸入賬戶密碼進(jìn)入操作系統(tǒng)到退出操作系統(tǒng)就是一個(gè)會(huì)話過(guò)程。會(huì)話較多用于網(wǎng)絡(luò)上,TCP的三次握手就創(chuàng)建了一個(gè)會(huì)話,TCP關(guān)閉連接就是關(guān)閉會(huì)話。
Http協(xié)議是一種無(wú)狀態(tài)協(xié)議,所以需要使用Session機(jī)制來(lái)保存用戶的狀態(tài),比如登錄狀態(tài)、常用信息等。
Session用于保存一次會(huì)話的相關(guān)信息,可以實(shí)現(xiàn)在多個(gè)頁(yè)面之間共享這些數(shù)據(jù)。
例如:你打開(kāi)淘寶登錄了個(gè)人賬號(hào),即使你瀏覽了再多的店鋪寶貝,切換了很多的頁(yè)面,用戶名是不變的,這個(gè)就是Session起的作用。直到你關(guān)閉瀏覽器,Session被銷毀,才會(huì)清除掉之前的登錄記錄。
今天和大家分享“Nginx+tomcat實(shí)現(xiàn)負(fù)載均衡的會(huì)話保持”就是實(shí)現(xiàn):如果網(wǎng)站某個(gè)負(fù)載節(jié)點(diǎn)掛掉,請(qǐng)求被分配到新節(jié)點(diǎn)Session也會(huì)同步過(guò)來(lái),實(shí)現(xiàn)會(huì)話保持,由此保證用戶無(wú)感知的瀏覽。
實(shí)現(xiàn)原理
使用Manager對(duì)象實(shí)現(xiàn)HTTP會(huì)話管理
DeltaManager作為會(huì)話管理器
用戶訪問(wèn)nginx,nginx負(fù)載均衡到tomcat,用于Tomcat集群的會(huì)話管理器,將所有session會(huì)話的改變同步給集群中的每一個(gè)節(jié)點(diǎn),實(shí)現(xiàn)會(huì)話復(fù)制。
實(shí)驗(yàn)配置
Nginx配置
測(cè)試環(huán)境單臺(tái)服務(wù)器開(kāi)了兩個(gè)tomcat,一臺(tái)對(duì)應(yīng)8080端口,另一臺(tái)對(duì)應(yīng)8090端口。
創(chuàng)建TomcatA TomcatB,分別配置tomcat server.xml
復(fù)制以下內(nèi)容到 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.224.145"
- port="4001"
- 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>
備注:
1.classname配置tomcat集群在進(jìn)行信息傳遞時(shí)互相使用什么類來(lái)進(jìn)行傳遞
channelsendoptions可以設(shè)置為2,4,8.10
2-確認(rèn)發(fā)送 4-同步發(fā)送 8-異步發(fā)送
10-在異步模式下,可以通過(guò)加上確認(rèn)發(fā)送(Acknowledge)來(lái)提高可靠性
2.manager決定如何管理集群的session信息
className-指定實(shí)現(xiàn)org.apache.catalina.ha.ClusterManager接口的類,用于信息之間的管理.
expireSessionsOnShutdown-設(shè)置為true時(shí),一個(gè)節(jié)點(diǎn)關(guān)閉,將導(dǎo)致集群下的所有Session失效
notifyListenersOnReplication-集群下節(jié)點(diǎn)間的Session復(fù)制、刪除操作,是否通知session listeners
3.Channel是Tomcat節(jié)點(diǎn)之間進(jìn)行通訊的工具。
Channel包括5個(gè)組件:Membership、Receiver、Sender、Transport、Interceptor
4.Membership維護(hù)集群的可用節(jié)點(diǎn)列表。用于檢測(cè)新增節(jié)點(diǎn)及掉線節(jié)點(diǎn)
address-組播地址(任意定義組播地址),如果需要阿里云ECS部署tomcat,因?yàn)镋CS不支持組播,建議改用memcache或redis存儲(chǔ)session實(shí)現(xiàn)會(huì)話保持
port-組播端口 (兩個(gè)tomcat組播端口要一致)
frequency-發(fā)送心跳(向組播地址發(fā)送UDP數(shù)據(jù)包)的時(shí)間間隔(單位:ms)。默認(rèn)值為500
dropTime-Membership在dropTime(單位:ms)內(nèi)未收到某一節(jié)點(diǎn)的心跳,則將該節(jié)點(diǎn)從可用節(jié)點(diǎn)列表刪除。默認(rèn)值為3000
5.Receiver : 接收器
address-接收消息的地址(默認(rèn)auto,但是在虛擬機(jī)上開(kāi)啟tomcat會(huì)報(bào)錯(cuò),建議配置本機(jī)IP地址)
port-接收消息的端口(如果在一臺(tái)服務(wù)器配置多個(gè)tomcat,需區(qū)分開(kāi)端口)
autoBind-端口的變化區(qū)間
如果port為4000,autoBind為100,接收器將在4000-4099間取一個(gè)端口,進(jìn)行監(jiān)聽(tīng)
selectorTimeout-NioReceiver 輪詢超時(shí)時(shí)間
maxThreads-線程池的***線程數(shù)
6.sender:發(fā)送器負(fù)責(zé)發(fā)送消息
- <Interceptor className="org.apache.catalina.tribes.group.interceptors.TcpFailureDetector"/>
- <Interceptor className="org.apache.catalina.tribes.group.interceptors.MessageDispatch15Interceptor"/>
- </Channel>
7.Valve :過(guò)濾器
8.Deployer:同步集群下的所有節(jié)點(diǎn)的一致性
9.ClusterListener : 監(jiān)聽(tīng)器,監(jiān)聽(tīng)Cluster組件接收的消息,使用DeltaManager時(shí),Cluster接收的信息通過(guò)ClusterSessionListener傳遞給DeltaManager
配置web.xml
在web.xml中添加屬性,用于告訴web容器,該項(xiàng)目屬于分布式項(xiàng)目
添加標(biāo)簽到web項(xiàng)目WEB-INF目錄
會(huì)話保持驗(yàn)證
webapps/ROOT/index.jsp 創(chuàng)建測(cè)試頁(yè)面獲取sessionID
- tomcatA
- <%@ page language="java" %>
- <html>
- <head><title>TomcatA</title></head>
- <body>
- <h1><font color="red">TomcatA</font></h1>
- <table align="centre" border="1">
- <tr>
- <td>Session ID</td>
- <% session.setAttribute("TomcatA","TomcatA"); %>
- <td><%= session.getId() %></td>
- </tr>
- <tr>
- <td>Created on</td>
- <td><%= session.getCreationTime() %></td>
- </tr>
- </table>
- </body>
- </html>
- tomcatB
- <%@ page language="java" %>
- <html>
- <head><title>TomcatB</title></head>
- <body>
- <h1><font color="red">TomcatB</font></h1>
- <table align="centre" border="1">
- <tr>
- <td>Session ID</td>
- <% session.setAttribute("TomcatB","TomcatB"); %>
- <td><%= session.getId() %></td>
- </tr>
- <tr>
- <td>Created on</td>
- <td><%= session.getCreationTime() %></td>
- </tr>
- </table>
- </body>
- </html>
瀏覽器訪問(wèn)驗(yàn)證
總結(jié):
tomcat實(shí)現(xiàn)會(huì)話保持有多種實(shí)現(xiàn)方式,這里只介紹了Manager對(duì)象實(shí)現(xiàn),優(yōu)點(diǎn)是利用tomcat自身集群session復(fù)制實(shí)現(xiàn)會(huì)話保持配置方便,缺點(diǎn)是像阿里云ECS這種不支持組播就無(wú)法用這種方式實(shí)現(xiàn)了。也可以使用memcache或redis存儲(chǔ)session會(huì)話,但這個(gè)要下載tomcat版本相對(duì)應(yīng)的memcache jar包。