使用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
     	 
       		
      	


第二种方式,在webApp应用的webApp\WebRoot\META-INF\目录下面增加context.xml,内容如下
	
	
       		
	




测试验证:
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:配置文件中的标签都是大写字母打头,如:是而不是,是而不是

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


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

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

这个时候需要如下配置不同tomcat的server.xml,修改

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

	
	
       		
			sticky="false"
			sessionBackupAsync="false"
    			requestUriIgnorePattern=".*\.(ico|png|gif|jpg|css|js)$"  
    			transcoderFactoryClass="de.javakaffee.web.msm.serializer.kryo.KryoTranscoderFactory"  />
	
这种方式的参考文章: https://code.google.com/archive/p/memcached-session-manager/

你可能感兴趣的:(session共享)