在部署cas系统的时候,遇到个问题,在tomcat集群部署cas系统,不能在一边服务器实现了登陆而在另一侧服务器还是没登录的。所以要实现tomcat集群的session的共享,从而实现高可用。
了解到的三种实现方式:
- 在nginx的upstream中加入ip_hash(这种不是session共享,个人理解是种取巧的方式,而且在一侧服务器宕机后,就会丢失登陆状态。)
- tomcat集群自带的session共享方式(个人尝试的时候,确认这种方式的tomcat集群需要部署在同一台服务器上,这样服务器宕机后,也是不能实现高可用的,但是的确很方便。可扩展行不高,可做为小集群时使用)
- tomcat集群与redis实现session共享(着重推荐)
简单来说下这三种方式,第一种,加入ip_hash的时候,相同ip请求第一次进入tomcat1,第二次也会进入tomcat1,从而实现了登陆状态的保持。但是可能对某一tomcat的负载会变大,而且ip网段相对集中的时候也会进入的是相同的tomcat。第二种,实现起来是真的轻松写意,只是效率会相对较低。第三种,通过添加的jar包,在每次请求的时候,会自动将session存入redis,或从redis获取session。
实现方式:
第一种:
upstream cas {
ip_hash;
server ip:port weight=1 max_fails=2 fail_timeout=30s;
server ip:port weight=1 max_fails=2 fail_timeout=30s;#换成自己的ip和端口
}
修改nginx.conf,完成后nginx -t ,nginx -s reload重启nginx。
第二种:
进入tomcat的安装路径,找到conf文件修改conf/server.xml。
在配置文件中将如下代码加在<Engine name="Catalina" defaultHost="localhost">
<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="/opt/tomcat/tmp/war-temp/"
deployDir="/opt/tomcat/tmp/war-deploy/"
watchDir="/opt/tomcat/tmp/war-listen/"
watchEnabled="false"/>
<ClusterListener className="org.apache.catalina.ha.session.JvmRouteSessionIDBinderListener"/>
<ClusterListener className="org.apache.catalina.ha.session.ClusterSessionListener"/>
</Cluster>
保存后,修改部署的项目,在web.xml中添加标签
<distributable/>
重启tomcat集群,即可实现session共享,千万注意!!tomcat集群需要在同一服务器上,否则不能实现session共享。
第三种:
首先安装redis,安装的事情,就不说了。安装成功后,启动。下载所需jar包
https://pan.baidu.com/s/1YIwxSUpWQoyclQnDlpKFnA 提取码:g5bh
将下载的jar包,放在tomcat安装路径的lib里,不是项目中的lib
修改tomcat安装路径conf/contxet.xml,将如下代码放在<Context>标签中即可
<Valve className="com.demo.redis_session.RedisSessionHandlerValve" /> <Manager className="com.demo.redis_session.RedisSessionManager" host="{redis.host}" port="{redis.port}" database="{redis.dbnum}" maxInactiveInterval="60"/>
如果是带密码的就在maxInactiveInterval前面加上password="redis.password"。不要直接复制,修改为你的参数再进行复制。
我提供的jar包,适用于tomcat8.0。若tomcat版本不是8.0就不要进行尝试了,我自测过,7.5和8.5都是不行的。可以自己下载项目进行修改后打包。下面是Github的地址,也可以去找适用于别的版本tomcat的jar包,注意修改value和Manager的className为对应jar包中的类,不然tomcat会报错,无法启动。
https://github.com/jcoleman/tomcat-redis-session-manager
上面是单一redis结点的搭建,下面说一说与redis集群的配合。
需要搭建redis集群的哨兵模式,注意需要是哨兵模式,关于redis集群搭建我也不赘述了,有很多帖子可以进行参考。
需要注意几个参数,一个是集群的名字,默认的是mymaster,可以不进行修改,还有就是每个哨兵结点的ip和port。依旧是上述的三个jar包,放置在tomcat的lib下,如果放过了,就直接修改参数即可。依旧是context.xml
<Valve className="com.demo.redis_session.RedisSessionHandlerValve" />
<Manager className="com.demo.redis_session.RedisSessionManager"
sentinelMaster="mymaster"
sentinels="ip:port,ip:port,ip:port,ip:port"
maxInactiveInterval="60"/>
通过配置文件可以看到,我使用了4个哨兵结点,修改为你的对应的哨兵结点就行。不要直接复制。
重启tomcat集群,集群即可实现session共享。
有关测试的问题,自己创建个测试war包,在界面上打印sessionId即可,若两次的sessionId保持一致,则session共享成功。
想了想还是提供个测试war包吧,这个也是当时在做session共享的时候看到帖子上的,感谢。下面是测试war包的下载地址:
https://pan.baidu.com/s/1X30DgnYKf-plBZ4q60na_g 提取码:m7gg
测试war包的访问路径是:http://ip:port/my_project/indexServlet。在没进行session共享的时候,相邻的两次请求的sessionId是不一致的,session共享搭建完成后,sessionId是一致的,就代表tomcat集群的session完成了。
最后,虽然我的session共享成功了,但是我所使用的cas4.2.7却还是依旧不给力,在session共享的情况下,不能实现登陆状态的保持,需要进行修改。这个会在之后帖子进行叙述。由于第一次长篇幅的帖子,哪里有错误出现,欢迎指正,谢谢。
------It's me xth_pope