tomcat官網
打開
tomcat
官網: http://tomcat.apache.org/ , 找到需要配置的tomcat版本的文檔,這裡以
tomcat7
為例,
找到對應的
Clustering
配置(因為配置session共享,就是配置叢集),如下圖
即,配置tomcat7叢集的文檔位址: http://tomcat.apache.org/tomcat-7.0-doc/cluster-howto.html
配置session共享
1.閱讀官方文檔
如上圖官方的文檔中所說,隻需配置
<Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"/>
節點即可
2.修改server.xml配置
但其實在
tomcat
的
conf/server.xml
的配置檔案中,已經有此項配置,隻是被注釋了,隻需将注釋 打開 即可,如下圖
3.準備測試環境
此時,準備一個
tomcat
,如上打開
conf/server.xml
中
Cluster
的節點配置,再準備一個簡單的
javaWeb應用
(列印
sessionId
,做驗證配置是否成功),放到
tomcat
的
webapps
目錄下
列印
sessionId
的
jsp
如下
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>session replication</title>
</head>
<body>
<br/>
<br/>
<br/>
<br/>
<br/>
SessionID:<%=session.getId() %>
</body>
</html>
因為是在本地做驗證,是以,再将以上配置完成的
tomcat
再複制一份,然後修改
tomcat
的端口,這裡我兩個
tomcat
的應用端口是
8081
和
8082
,如下圖所示
tomcat
的
webapps
目錄,如下
4.測試失敗
修改完成配置之後,分别啟動
tomcat
,打開浏覽器測試之後,如下
測試發現,兩個
tomcat
的
sessionId
并不一緻?!
另外,還發現了一個問題,就是 來回重新整理 浏覽器的的index.jsp,浏覽器顯示的 兩個
兩個tomcat的應用
在不斷的變化 ,但是這個問題跟配置
sessionId
無關,是
session共享
導緻的,後續再單獨寫一篇筆記講。
cookie的作用域
5.查漏補缺
此時我們再傳回
tomcat
官網配置
Cluster
的文檔處,繼續閱讀,找到其中的
Cluster Basics
标簽那,如下圖所示,
文檔中,說要配置
session複制
必須完成以下幾步:
- session 的所有 attributes 必須實作 java.io.Serializable (√)
- 在 server.xml 的配置檔案中,把 Cluster 的注釋打開 (√)
- 如果有自定義的叢集 Valve(tomcat過濾器),就需要在 server.xml 的 Cluster 節點下配置 ReplicationValve (x,沒有,不用管)
- 如果叢集的 tomcat執行個體 在同一台機器上,需要確定的你的 Receiver.port 不要有沖突,然後還順道贊美了他家的 tomcat ,在大部分場景下能夠自動檢測4000-4100範圍内的可用端口來,解決此問題 (√,預設配置就已經支援了)
- 需要在 web應用 的 web.xml 檔案中,配置
節點 (x,這個沒有配)<distributable/>
- 如果叢集用到了 mod_jk,就要在 server.xml 的 Engine 節點配置 jvmRoute 的屬性,如
并且 jvmRoute 屬性值與 workers.properties 中的 worker name 比對 (x,沒配,不用管)<Engine name="Catalina" jvmRoute="node01" >
- 叢集的所有節點,系統時間要一緻,并與 NTP service 同步 (√,同一台機器)
- 将負載均衡伺服器(apache、nginx等),配置為粘性會話模式 (x,暫時沒有配負載均衡,不用管)
是以,意思就是,在
conf/server.xml
中配置了
Cluster
節點外,還需要在
web應用
的
web.xml
檔案裡面配置
<distributable/>
節點,如下圖所示
6.重新測試
配置完成之後,重新啟動兩個
tomcat
,重新重新整理浏覽器的頁面,此時如下圖所示,sessionId 已經一緻,即
session共享
配置成功。
探究
1.Cluster 節點的預設配置是什麼?
上文在官網中截取的,配置 Cluster 節點的圖,如下所示,
圖中最後提到的,
The following is the default cluster configuration
如下配置,
<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>
即配置
<Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"/>
與上面這一大段的配置内容,效果是一樣的,但是這樣一來,細粒度越小,可以調整的内容也就越多
在上面的這麼多配置中,需要注意的是,
address="228.0.0.4"
這個位址為 多點傳播位址,屬于
ip位址
中的
D類位址
這個位址可以改,但是隻能改為另一個多點傳播位址。如果随便填一個非多點傳播位址,tomcat啟動的時候會報一個
Not a multicast address
的錯誤,這個報錯來自
java
的
java.net.MulticastSocket
,如下所示,
在配置了
Cluster
節點之後,
tomcat
啟動的過程中,會調用
org.apache.catalina.tribes.membership.McastService
的
start()
方法,然後在方法中驗證
address
的值是否是一個多點傳播位址(
D類位址
,它的第1個位元組的前四位固定為
1110
,即
ipv4
的位址的下限為
224.0.0.1
)
2.tomcat之間如何進行session複制的通信?
在
tomcat
文檔的最後,有講到這個問題:
當配置了
Cluster
節點的
tomcat
啟動的時候,會建立
Host
對象,并用一個叢集對象與之關聯。啟動過程中,到了解析
Context
(即
web應用
)的時候,如果
web應用
的
web.xml
配置了
<distributable/>
的節點,則
Cluster
的對象會建立一個
manager
去管理
session複制
。之後,
Cluster
的對象将啟動一個
membership
的服務(多點傳播)和一個
replication
的服務(tcp單點傳播)。下圖是關于上述描述的
tomcat源碼
。
Tomcat
之間的
session replication
通信是使用簡單的
多點傳播ping
建立的。每個
Tomcat執行個體
将定期發出
多點傳播ping
,在
ping消息
中,會包含
Tomcat執行個體
的
IP
和
TCP偵聽端口
去進行 與其他執行個體的
session複制
。如果
Tomcat執行個體
在給定的時間範圍内沒有收到此類ping,則該成員被視為已死。
當
Tomcat執行個體
收到
多點傳播ping
,該成員就會被添加到叢集中,在下一個複制請求時,發送執行個體将通過叢集的成員清單偵聽的
ip和端口
資訊(單點傳播)建立
TCP Socket連接配接
,進行
session複制
。
多點傳播傳輸:在發送者和每一接收者之間實作點對點網絡連接配接,如果一台發送者同時給多個接收者傳輸相同的資料,也隻需要複制一份的相同資料包,它提高了資料的傳輸效率。
在網際網路中的IP多點傳播也是用多點傳播組的概念,每個組都有一個特别配置設定的位址,要給該組發送的計算機将使用這個位址作為分組的目标位址。在IPv4中,這些位址在D類位址空間中配置設定,而IPv6也有一部分位址空間保留給多點傳播組。
需要注意的是,主機多點傳播時僅發送一份資料,隻有資料在傳送路徑出現分岔時才将分組複制後繼續轉發。
即,在
Tomcat
啟動時,發送
多點傳播ping
建立叢集的成員清單。在下一個
session複制
的請求時,根據叢集成員清單的各成員偵聽的
ip和端口
,逐一建立
socket連接配接
,進行
session複制
。