Tomcat的session共享方案--memcached-session-manager

在线项目中经常需要多台tomcat进行负载均衡,比如一台nginx+多台tomcat的部署形式。这样部署对需要保持登录状态的应用带了一个新的问题,各tomcat之间的session因为是独立保存所以会造成用户登录状态无效。

可能的解决方法:

  1. 独立保存session,供各tomcat共享访问。具体保存到什么地方就比较多,如本例的memcached。

  2. 使用nginx的ip_hash或sticky,相对来说sticky比ip_hash靠谱。

  3. 使用tomcat自带的session复制功能,基于多播的session复制,配置起来稍显复杂。

  4. 使用cookie代替session,特定情况下确实是最简单的方案,不过一般不建议在cookie中存储过多数据。

基于memcached-session-manager的tomcat共享

参考文档:https://code.google.com/p/memcached-session-manager/wiki/SetupAndConfiguration

配置步骤只需两步

  1. 将memcached-session-manager-${version}.jar 、memcached-session-manager-tc7-${version}.jar、spymemcached-2.11.1.jar三个jar包放到tomcat的lib目录下。

  2. 修改tomcat配置文件conf/context.xml,添加如下内容:

<Context>
     ...
    <Manager className="de.javakaffee.web.msm.MemcachedBackupSessionManager"
        memcachedNodes="n1:localhost:11211"
        sticky="false"
        sessionBackupAsync="false"
        requestUriIgnorePattern=".*\.(ico|png|gif|jpg|css|js)$"
    />
</Context>

启动tomcat,如果日志出现如下内容则表示配置成功:

Apr 13, 2015 6:13:11 PM de.javakaffee.web.msm.MemcachedSessionService startInternal
INFO: --------
-  finished initialization:
- sticky: false
- operation timeout: 1000
- node ids: [n1]
- failover node ids: []
- storage key prefix: null
--------

需要注意的地方:

1.tomcat6、7、8分别对应的版本是session-manager-tc6-${version}.jar、session-manager-tc7-${version}.jar、session-manager-tc8-${version}.jar,另tomcat7需要7.0.23+。

2.如果多台tomcat之间的session不能共享,则检查是否配置有差异。

其他的配置参数说明

className

必选项,可配置为de.javakaffee.web.msm.MemcachedBackupSessionManager和de.javakaffee.web.msm.DummyMemcachedBackupSessionManager。其中DummyMemcachedBackupSessionManager可用于测试环境,不需要真实存在memcached。

memcachedNodes

必选项,memcached的节点信息,格式如:memcachedNodes="n1:app01:11211,n2:app02:11211"。

failoverNodes 

可选项,不能使用在non-sticky sessions模式。故障转移配置节点,多个使用空格或逗号分开,配置某个节点为备份节点,当其他节点都不可用时才会存储到备份节点,官方建议配置为和tomcat同服务器的节点。

理由如下:

假如有两台服务器m1,m2,其中m1部署tomcat和memcached节点n1,m2部署memcached节点n2。

如果配置tomcat的failoverNodes值为n2或者不配置,则当服务器m1挂掉后n1和tomcat中保存的session会丢失,而n2中未保存或者只保存了部分session,这就造成部分用户状态丢失。

如果配置tomcat的failoverNodes值为n1,则当m1挂掉后因为n2中保存了所有的session,所以重启tomcat的时候用户状态不会丢失。 

为什么n2中保存了所有的session? 因为failoverNodes配置的值是n1,只有当n2节点不可用时才会把session存储到n1,所以这个时候n1中是没有保存任何session的。

username 

可选项,SASL的用户名,如果节点保护membase的bucket uri。

password 

可选项,和username搭配使用。

memcachedProtocol

可选项,默认text,memcached使用的协议,可选值:text,binary。

sticky 

 可选项,默认true,制定是否使用粘性session模式。

lockingMode

可选值,默认none,只对non-sticky有效。

requestUriIgnorePattern 

可选值,制定忽略那些请求的session操作,一般制定静态资源如css,js一类的。

sessionBackupAsync 

可选值,默认true,是否异步的方式存储到memcached。

backupThreadCount 

可选项,默认是cpu核心数,异步存储session的线程数。

sessionBackupTimeout 

可选项,默认100毫秒,异步存储session的超时时间。

operationTimeout 

可选项,默认1000毫秒,memcached的操作超时时间。

storageKeyPrefix 

可选值,默认值webappVersion,存储到memcached的前缀,主要是为了区分多个webapp共享session的情况。可选值:静态字符串、host、context、webappVersion,多个使用逗号分割。

sessionAttributeFilter 

可选值,通过正则表达式确定那些session中的属性应该被存储到memcached。例子如:sessionAttributeFilter="^(userName|sessionHistory)$"。

transcoderFactoryClass 

可选值,默认值de.javakaffee.web.msm.JavaSerializationTranscoderFactory,制定序列化和反序列化数据到memcached的工厂类。

可能值如下:

  • Java serialization: de.javakaffee.web.msm.JavaSerializationTranscoderFactory

  • Kryo based serialization: de.javakaffee.web.msm.serializer.kryo.KryoTranscoderFactory

  • Javolution based serialization: de.javakaffee.web.msm.serializer.javolution.JavolutionTranscoderFactory

  • XStream based serialization: de.javakaffee.web.msm.serializer.xstream.XStreamTranscoderFactory

    copyCollectionsForSerialization

    可选值,默认false,遍历集合的时候是否直接使用要遍历的对象还是遍历复制一份的集合副本,同一个集合对象多线程修改的时候,会造成遍历操作的线程执行异常。

    customConverter

    可选值,自定义特定类型的序列化方式。

    enableStatistics 

    可选值,默认true,是否启动统计报表,具体查询方式参考 JMXStatistics 。

    enabled

    可选值,默认ture,是否启用将session保存到memcached,仅支持粘性模式(sticky mode)。可以在运行时通过JMX改变。

    提交评论