使用memcached实现tomcat集群中Session共享业务场景

业务场景描述:
有这样的业务架构,一台nginx将客户端请求分发到2台tomcat中,现在的问题是当tomcat1挂掉之后,nginx将请求转发到tomcat2中,此时tomcat2会要求用户重新登入,造成用户感知不好(实际用户已经登入成功过了)。
现在想做到tomcat1挂掉之后,当nginx将请求分发到tomcat2的时候,不让用户再次登入,即完成两个tomcat的Session共享功能



解决方案:

1:安装并启动Memcached
Memcached的安装和服务启动,请参考本人编写的博文《MemCached的安装和JAVA客户端连接Memcached示例代码》,记得一定要保证Memcached能连接,用Java客户端缓存数据后在取出来试一下。

2:下载需要的包,tomcat7版本,这里面坑很多,切记版本一致一致一致,不然启动报错,把你绕死
asm-3.2.jar
couchbase-client-1.4.8.jar:msm依赖这个包
kryo-1.04.jar
kryo-serializers-0.9.jar
memcached-session-manager-1.6.5.jar
memcached-session-manager-tc7-1.6.5.jar:不同版本Tomcat需要使用不同的Jar包,tc7代表tomcat7版本
minlog-1.2.jar
msm-kryo-serializer-1.6.0.jar
reflectasm-1.01.jar
spymemcached-2.10.3.jar:Jave客户端连接memcached的jar包,这个包可以选择安装memcached安装版本对应的jar包
    将上面这些包放到tomcat的lib目录下面,记得是tomcat的lib目录,不是web应用的lib目录

3:配置web应用
这里有两种方式修改web应用,让应用在启动的时候连接memcached服务,并同步tomcat Session。
第一种方式,修改tomcat的server.xml
     	 <Context docBase="webApp" path="/" reloadable="false" source="org.eclipse.jst.jee.server:webApp">
       		<Manager className="de.javakaffee.web.msm.MemcachedBackupSessionManager"  
    			memcachedNodes= "n1:111.111.111.1:11211"
    			requestUriIgnorePattern=".*\.(ico|png|gif|jpg|css|js)$"  
    			transcoderFactoryClass="de.javakaffee.web.msm.serializer.kryo.KryoTranscoderFactory"  />
      	</Context>


第二种方式,在webApp应用的webApp\WebRoot\META-INF\目录下面增加context.xml,内容如下
	<?xml version="1.0" encoding="UTF-8"?>
	<Context>
       		<Manager className="de.javakaffee.web.msm.MemcachedBackupSessionManager"  
    			memcachedNodes= "n1:111.111.111.1:11211"
    			requestUriIgnorePattern=".*\.(ico|png|gif|jpg|css|js)$"  
    			transcoderFactoryClass="de.javakaffee.web.msm.serializer.kryo.KryoTranscoderFactory"  />
	</Context>




测试验证:
1:只启动一台经过配置的tomcat
浏览器中登入系统,请求一个接口,可以看到接口请求中的Request Header中带了JSESSION属性,后台日志打印也有JSESSION属性,
这时关闭tomcat服务器,然后在重启服务器完成之后,还是在上面开启的浏览器中请求另外一个接口,可以看到请求中的Request Header中带了JSESSION属性没变,后台日志中JSESSION属性也没变,memcached中管理的session同步过来了,不需要再次登入了。
2:启动两台tomcat,nginx配置分发到这两台服务器,两台服务器互为主备
浏览器中登入系统,请求一个接口,可以看到接口请求中的Request Header中带了JSESSION属性,后台日志打印也有JSESSION属性,
这时关闭tomcat1服务器, 同浏览器中继续请求接口,可以看到请求中的Request Header中JSESSION属性没变,tomcat2中后台日志JSESSION属性没变,不要再次登入系统验证。
这时启动tomcat1,关闭tomcat2, 同浏览器中继续请求接口,可以看到请求中的Request Header中JSESSION属性没变,tomcat1中后台日志JSESSION属性也没变,业务场景功能实现啦。


走过的坑:

1:确保memcached能通,能缓存资源
2:下载的Jar包放到tomcat的lib目录中,不是web应用的lib目录
3:切记下载的jar包的版本一致,不然各种缺少列
4:注意选择合适的修改应用的配置方式
5:配置文件中的标签都是大写字母打头,如:是<Context>而不是<context>,是<Manager>而不是<manager>

6:升级生产环境的时候,一般生产环境都有端口和防火墙隔离的,记得需要将和memcached交互的端口打开


如上配置的不足点与解决方法:
如上的配合会导致A机器session变动,不同同步到B机器同session,可以有如下两种方式解决此问题:

一:修改tomcat的server.xml(这种方式会偶尔出现session变动的情况,不太稳定)

这个时候需要如下配置不同tomcat的server.xml,修改<Engine属性,最后加上jvmRoute属性,这样就可以强制session变化后备份到memcached,并且另外一台机器要使用session的时候从memcached中获得,详细配置如下

<Engine name="Catalina" defaultHost="localhost" jvmRoute="jvm1">

二:修改memcached-session-manage的同步方式,在webApp应用的webApp\WebRoot\META-INF\目录下面增加context.xml,内容如下

	<?xml version="1.0" encoding="UTF-8"?>
	<Context>
       		<Manager className="de.javakaffee.web.msm.MemcachedBackupSessionManager"  
    			memcachedNodes= "n1:111.111.111.1:11211"
			sticky="false"
			sessionBackupAsync="false"
    			requestUriIgnorePattern=".*\.(ico|png|gif|jpg|css|js)$"  
    			transcoderFactoryClass="de.javakaffee.web.msm.serializer.kryo.KryoTranscoderFactory"  />
	</Context>

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值