本公众号内容大多由平时操作整理记录,如果有错误的地方欢迎留言指正
在前面一篇内容的基础上Tomcat负载调度简单配置
进一步进行配置,实现后端小规模集群的session共享
tomcat集群
tomcat的集群session共享方案只适合在小规模集群中(5台左右)使用,当集群节点数量过多时,节点间session复制会产生网络带宽的瓶颈,会产生session复制延迟
源码安装tomcat
#下载
[root@tomcat-1 ~]# wget http://www-us.apache.org/dist/tomcat/tomcat-7/v7.0.90/bin/apache-tomcat-7.0.90.tar.gz
[root@tomcat-1 ~]# tar zxf apache-tomcat-7.0.90.tar.gz -C /usr/local/
[root@tomcat-1 local]# ln -sv apache-tomcat-7.0.90/ tomcat
"tomcat" -> "apache-tomcat-7.0.90/"
#添加环境变量
[root@tomcat-1 ~]# vim /etc/profile.d/tomcat.sh
export CATALINA_BASE=/usr/local/tomcat
export PATH=$CATALINA_BASE/bin:$PATH
#重载变量
[root@tomcat-1 ~]# source /etc/profile.d/
启动服务:
[root@tomcat-1 ~]# /usr/local/tomcat/bin/catalina.sh start
Using CATALINA_BASE: /usr/local/tomcat
Using CATALINA_HOME: /usr/local/tomcat
Using CATALINA_TMPDIR: /usr/local/tomcat/temp
Using JRE_HOME: /usr
Using CLASSPATH: /usr/local/tomcat/bin/bootstrap.jar:/usr/local/tomcat/bin/tomcat-juli.jar
Tomcat started.
配置示例
可以根据官网的示列进行参考配置:tomcat集群配置示例
启用tomcat集群,添加如下定义到< Engine > 或 < Host > 标签中:
<Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"/>
定义在< Engine >中对所有Host都生效,定义在< Host > 中仅对当前Host生效。
使用上述配置将使用DeltaManagerto replicate session deltas 启用所有会话复制。通过all-to-all,意味着会话被复制到集群中的所有其他节点。这适用于较小的集群(5台左右),但不建议将其用于较大的集群(很多Tomcat节点)。此外,在使用增量管理器时,它将复制到所有节点,甚至是未部署应用程序的节点。这种方式并不可靠。默认不会启用这功能
启用tomcat集群默认会使用以下配置:
多播地址为228.0.0.4
多播端口为45564 : 用于集群成员关系判断,该端口监地址不能是127.0.0.1
会话复制端口使用范围 : 4000-4100,默认从4000依次开始
监听器已配置 ClusterSessionListener
两个监听器TcpFailureDetector和MessageDispatch15Interceptor
配置示例:
<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" #探测时间间隔 0.5秒
dropTime="3000"/> #定义失败时长,3秒
<Receiver className="org.apache.catalina.tribes.transport.nio.NioReceiver" #定义如何接收其他节点的会话消息
address="auto" #监听地址,多网卡可以指定具体一个网卡地址,不能是127.0.0.1
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>
除此外,实现集群的会话复制还要注意如下的配置
各节点时间同步
如果您使用的是mod_jk,确保在引擎上设置< Engine name="Catalina" jvmRoute="node01" >
确保要在web.xml中进行会话复制的应用程序定义< distributable/ >元素,不加不会生效
确保会话不丢失,最好做会话绑定
配置tomcat集群
node01节点修改server.xml,在Host标签中添加如下内容:
<Engine name="Catalina" defaultHost="localhost" jvmRoute="node01">
<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.199"
port="45564"
frequency="500"
dropTime="3000"/>
<Receiver className="org.apache.catalina.tribes.transport.nio.NioReceiver"
address="192.168.214.143"
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>
node02节点修改server.xml配置文件,在Host标签添加如下配置:
<Engine name="Catalina" defaultHost="localhost" jvmRoute="node02">
<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.199"
port="45564"
frequency="500"
dropTime="3000"/>
<Receiver className="org.apache.catalina.tribes.transport.nio.NioReceiver"
address="192.168.214.147"
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>
默认站点目录没有web.xml文件,可以复制tomcat的全局web.xml值站点目录WEB-INF下,web.xml在安装目录下是对所有站点程序生效,是全局配置,通常每个站点程序都会有单独的web.xml。
[root@tomcat-1 ~]# sp /usr/local/tomcat/conf/web.xml /usr/local/tomcat/webapps/ROOT/WEB-INF/
#在web.xml的合适位置添加<distributable/>标签即可
[root@tomcat-1 WEB-INF]# vim web.xml
<distributable/>
同样,node02节点也要添加
后端node01,node02节点的nginx设置反向代理
server {
listen 80 default_server;
server_name localhost;
root /usr/local/tomcat/webapps/ROOT;
index index.html index.jsp;
location ~* \.jsp$ {
proxy_pass http://127.0.0.1:8080;
}
error_page 404 /404.html;
}
配置完成后重启服务,观察日志内容:/var/log/tomcat/catalina.2018-07-18.log
Replication member added:org.apache.catalina.tribes.membership.
MemberImpl[tcp://{192, 168, 214, 147}:4000,{192, 168, 214, 147},
4000, alive=1028, securePort=-1,
UDP Port=-1, id={104 85 -63 -23 4 43 66 52 -87 121 -76 -2 57 69 102 -46 },
payload={}, command={}, domain={}, ]
各节点看到上面的日志内容说明后端集群各节点成员关系的判定已经成功了。接下来测试访问
此时刷新页面Session id是不会改变的。
其他
由于会话是绑定在后端服务器,因此前端的调度器无论使用什么调度算法都没有意义的。在上面的架构中,如果后端服务有一个节点宕机了,那么另一个节点任然可以继续提供请求,并且宕机节点上的会话在另一节点上已经被复制。
一开始使用yum安装的tomcat部署出现一些问题,google一下发现这类问题出现比较少,并不是权限和端口的问题,也没有找到问题所在,最终规避的方式是卸载yum安装的tomcat,到官网下载压缩包安装就没有遇到该问题

