利用Redis 实现多tomcat 同一用户同一环境单一在线
2016-03-02 23:46
405 查看
在实际开发中,我们需要控制一个用户在pc和app的同类型环境下只能登录一个,最多可以pc和app同时在线。
在单一的tomcat环境中,我们可以通过建立一个全局的map,存放用户名(id)+登录环境(APP或PC)和对应的session。按如下方法实现:
1、session里保存用户名id和登录方式。
2、每次用户登录的时候判断是否有重复的登录,有的话就将原来的session失效,没有就保存到map里。
3、监听session,在session destroy事件处理里负责根据session里的值找到对应的map里面的key-value键值对并将其删除。
但在多tomcat环境下,我们可以通过redis 实现tomcat的session的共享:
配置很简单,:
1、在context.xml里配置(注意不要在server.xml里配置)
<ValveclassName="com.orangefunction.tomcat.redissessions.RedisSessionHandlerValve"
/>
<ManagerclassName="com.orangefunction.tomcat.redissessions.RedisSessionManager"
host="localhost"
port="6379"
database="0"
maxInactiveInterval="60"/>
2、将下列jar放到tomcat的lib下面
tomcat-redis-session-manager-2.0.0
jredis-2.8
commons-pool2-2.3
3、注意不要在webapp对应的应用的lib里包含tomcat-redis-session-manager-2.0.0 包,否则会报错。当时同事用的maven,打包的时候把omcat-redis-session-manager-2.0.0 包一并打进去,出现错误,找了半天才找到。
原来想法很简单,只有把对应的全局的map保存到redis里就可以了,但发现在应用层HttpSession对象根本不支持序列化,无法保存到redis里。
同时发现tomcat的session在redis里是把sessionId作为key来保存的,但同样对应的value,取出后该对象不是HttpSession,没法按照HttpSession的方法将session失效(调用session.invalidate()方法)
解决办法如下:
1、不使用全局的map,直接将存放用户名(id)+登录环境(APP或PC)作为键值,对应的sessionid作为value保存到redis里。(注意这里不保存session)
2、每次用户登录的时候判断是否有重复的登录,有的话就将原来的session失效,失效的方法是直接将sessionid键值从redis里删除。如果没有就按照1的方式保存到redis里。
3、监听session,在session destroy事件处理里负责根据session里的值找到对应的redis里面的key-value键值对并将其删除。
用上面的方式实现了功能,但同时发现还遗漏了一个问题,就是session是有过期的,他在redis里tomcat设置了对应的有效时间,而我们的用户登录信息的生命周期应该和其对应session同步。因此我们需要进行如下改造:
1、保存信息到redis里的时候同时设置有效时间。
2、增加一个filter,对所有信息进行拦截,filter里对该session对应的保存在redis里的登录信息设置有效时间。
至此,所有的问题都解决。
在单一的tomcat环境中,我们可以通过建立一个全局的map,存放用户名(id)+登录环境(APP或PC)和对应的session。按如下方法实现:
1、session里保存用户名id和登录方式。
2、每次用户登录的时候判断是否有重复的登录,有的话就将原来的session失效,没有就保存到map里。
3、监听session,在session destroy事件处理里负责根据session里的值找到对应的map里面的key-value键值对并将其删除。
但在多tomcat环境下,我们可以通过redis 实现tomcat的session的共享:
配置很简单,:
1、在context.xml里配置(注意不要在server.xml里配置)
<ValveclassName="com.orangefunction.tomcat.redissessions.RedisSessionHandlerValve"
/>
<ManagerclassName="com.orangefunction.tomcat.redissessions.RedisSessionManager"
host="localhost"
port="6379"
database="0"
maxInactiveInterval="60"/>
2、将下列jar放到tomcat的lib下面
tomcat-redis-session-manager-2.0.0
jredis-2.8
commons-pool2-2.3
3、注意不要在webapp对应的应用的lib里包含tomcat-redis-session-manager-2.0.0 包,否则会报错。当时同事用的maven,打包的时候把omcat-redis-session-manager-2.0.0 包一并打进去,出现错误,找了半天才找到。
原来想法很简单,只有把对应的全局的map保存到redis里就可以了,但发现在应用层HttpSession对象根本不支持序列化,无法保存到redis里。
同时发现tomcat的session在redis里是把sessionId作为key来保存的,但同样对应的value,取出后该对象不是HttpSession,没法按照HttpSession的方法将session失效(调用session.invalidate()方法)
解决办法如下:
1、不使用全局的map,直接将存放用户名(id)+登录环境(APP或PC)作为键值,对应的sessionid作为value保存到redis里。(注意这里不保存session)
2、每次用户登录的时候判断是否有重复的登录,有的话就将原来的session失效,失效的方法是直接将sessionid键值从redis里删除。如果没有就按照1的方式保存到redis里。
3、监听session,在session destroy事件处理里负责根据session里的值找到对应的redis里面的key-value键值对并将其删除。
用上面的方式实现了功能,但同时发现还遗漏了一个问题,就是session是有过期的,他在redis里tomcat设置了对应的有效时间,而我们的用户登录信息的生命周期应该和其对应session同步。因此我们需要进行如下改造:
1、保存信息到redis里的时候同时设置有效时间。
2、增加一个filter,对所有信息进行拦截,filter里对该session对应的保存在redis里的登录信息设置有效时间。
至此,所有的问题都解决。
相关文章推荐
- java-模拟tomcat服务器
- i-jetty环境搭配与编译
- 实现单Tomcat多Server配置
- 生产环境下的Tomcat配置
- redis安装问题小结
- Linux部署Tomcat服务器
- jenkins------结合maven将svn项目自动部署到tomcat下
- 如何搞定tomcat这只喵~
- kindeditor 批量上传 上传失败 thinkphp swfupload session
- 使用 Redis 和 Python 构建一个共享单车的应用程序
- Redis偶发连接失败案例实战记录
- 杰奇登录后的东西都是在session里面的
- Redis中实现查找某个值的范围
- redis的hGetAll函数的性能问题(记Redis那坑人的HGETALL)
- Redis和Memcached的区别详解
- 分割超大Redis数据库例子
- Redis总结笔记(一):安装和常用命令
- Redis sort 排序命令详解