集群方式
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