集群方式
tomcat集群一共有下面幾種方式:
- Apache Tomcat Clustering
- JWT機制
- MSM、Tomcat+Redis等統一Session管理
詳細
Apache Tomcat Clustering
這個是tomcat自帶的集群方式,好處是配置簡單,缺點是session共享時,使用帶寬比較高,性能比較差,適合小集群使用
配置方式
- 在server.xml中找到
<!--
<Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"/>
-->
在下面粘貼下面內容:
<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.ClusterSessionListener"/>
</Cluster>
這里其實沒有什么需要改的,在多個tomcat下的server.xml都粘貼上并保持一致
- 在web.xml中添加 <distributable/>標簽
MSM
MSM是Tomcat+Memcached,使用Memcached管理session
這里有一個點要注意的就是有兩種配置方式,一種是sticky粘性配置,一種是non-sticky配置,具體區別:
non-sticky:tomcat每次都會訪問memcached
sticky:tomcat會先操作本地的Session,當達到閾值時才會寫
優點:通用性強
缺點:效率達不到極致
Memcached,如果這個時候另一個tomcat需要Session,則復制session到TomcatB對應的memcached主節點中
優點:如果能保證同ip分配到同一個tomcat中,效率高
缺點:
1.容易造成熱點數據的訪問,大部分請求都到了同一tomcat
2.單點故障,因為是先寫入本地tomcat的session,后面才回寫到memcached,如果此時tomcat發生故障,沒有回寫的數據就會丟失
3.如果不能保證同一個ip同一個tomcat處理,則效率非常低
non-sticky配置
- 修改conf/Context.xml
<Manager className="de.javakaffee.web.msm.MemcachedBackupSessionManager"
memcachedNodes="n1:192.168.139.145:2222,n2:192.168.139.145:3333"
sticky="false"
sessionBackupAsync="false"
lockingMode="auto"
requestUriIgnorePattern=".*\.(ico|png|gif|jpg|css|js)$"
transcoderFactoryClass="de.javakaffee.web.msm.serializer.kryo.KryoTranscoderFactory"
/>
這里要注意的是:
1.把sticky設置成false,非粘性
2.memcachedNodes就是填memcached節點地址
3.lockingMode:并發請求session時的鎖定方式,一共有四種:
none:session不被鎖定
all:session會被鎖定直到請求結束
auto:檢測到只讀請求不會鎖定,非只讀請求鎖定
uriPattern:<regexp>:如果requestURI+"?"+queryString匹配配置的表達式,session將不被鎖定
4.requestUriIgnorePattern:匹配的資源將不會被session備份
- 測試結果
準備兩個tomcat,部署測試代碼到tomcat中
測試代碼如下:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>測試Session共享內容</title>
</head>
<body>
<%
Object sessionMessage = session.getAttribute("sessionMessage");
if (sessionMessage!=null && sessionMessage.toString().trim().length()>0) {
out.println("session有值 session="+sessionMessage);
}else{
session.setAttribute("sessionMessage","Hello imooc jiangzh");
out.println("session沒有值");
}
%>
</body>
</html>
分別請求http://localhost:8080和http://localhost:8090/
sticky配置
- 修改server.xml
<!-- You should set jvmRoute to support load-balancing via AJP ie :
<Engine name="Catalina" defaultHost="localhost" jvmRoute="jvm1">
-->
<Engine name="Catalina" defaultHost="localhost" jvmRoute="jvmb">
在Engine節點中添加jvmRoute屬性,這里每個tomcat要配置不同名字,通過注釋可以知道使用了做負載均衡的
- 配置config/context.xml
<Manager className="de.javakaffee.web.msm.MemcachedBackupSessionManager"
memcachedNodes="n1:192.168.139.145:2222,n2:192.168.139.145:3333"
sticky="true"
sessionBackupAsync="false"
failoverNodes="n1"
requestUriIgnorePattern=".*\.(ico|png|gif|jpg|css|js)$"
transcoderFactoryClass="de.javakaffee.web.msm.serializer.kryo.KryoTranscoderFactory"
/>
說明:
1.sticky配置true
2.添加failoverNodes屬性,不同tomcat配置不一樣名字
failoverNodes:(這是只能用于sticky配置的)
This attribute must contain the ids of the memcached nodes that must only be used for session backup when none of the other memcached nodes are available. Therefore, you should list those memcached nodes, that are running on the same machine as this tomcat. E.g. if you have tomcat1 and memcached1 (n1) running on host1, and tomcat2 and memcached2 (n2) on host2, then you set n1 as failover node for tomcat1, so that tomcat1 does only store sessions in memcached1 if memcached2 is not available (for tomcat2 failoverNodes would be set to n2). With this setting host1 could completely crash and sessions from tomcat1 would still be available.
簡單來說就是當memcached節點down后備份用的
- 測試
同上面non-sticky
參考
https://github.com/magro/memcached-session-manager/wiki/SetupAndConfiguration#example-for-non-sticky-sessions--kryo
http://yuanhsh.iteye.com/blog/2191934