Tomcat7基于Redis的Session共享实战二

目前,为了使web能适应大规模的访问,需要实现应用的集群部署。集群最有效的方案就是负载均衡,而实现负载均衡用户每一个请求都有可能被分配到不固定的服务器上,这样我们首先要解决session的统一来保证无论用户的请求被转发到哪个服务器上都能保证用户的正常使用,即需要实现session的共享机制。

在集群系统下实现session统一的有如下几种方案:
(1) 应用服务器间的session复制共享(如tomcat自带session共享)
(2) 基于cache DB缓存的session共享

一、应用服务器间的session复制共享(Tomcat自带的功能)
session复制共享,主要是指集群环境下,多台应用服务器之间同步session,使session保持一致,对外透明。 如果其中一台服务器发生故障,根据负载均衡的原理,web服务器(apache/nginx)会遍历寻找可用节点,分发请求,由于session已同步,故能保证用户的session信息不会丢失。

此方案的不足之处:
技术复杂,必须在同一种中间件之间完成(如:tomcat-tomcat之间).
session复制带来的性能损失会快速增加.特别是当session中保存了较大的对象,而且对象变化较快时, 性能下降更加显著. 这种特性使得web应用的水平扩展受到了限制。
Session内容序列化(serialize),会消耗系统性能。
Session内容通过广播同步给成员,会造成网络流量瓶颈,即便是内网瓶颈。

二、基于 Memcached 缓存的 session 共享
即使用cacheDB存取session信息,应用服务器接受新请求将session信息保存在cache DB中,当应用服务器发生故障时,web服务器(apache/nginx)会遍历寻找可用节点,分发请求,当应用服务器发现session不在本机内存时,则去cache DB中查找,如果找到则复制到本机,这样实现session共享和高可用。
目前有开源的msm用于解决tomcat之间的session共享:Memcached_Session_Manager(MSM)
http://code.google.com/p/memcached-session-manager/
一个高可用的Tomcat session共享解决方案,除了可以从本机内存快速读取Session信息(仅针对黏性Session)外,同时可使用memcached存取Session,以实现高可用。

特性
支持Tomcat6、Tomcat7支持黏性、非黏性Session
无单一故障点
可处理tomcat故障转移
可处理memcached故障转移
插件式session序列化
允许异步保存session,以提升响应速度
只有当session有修改时,才会将session写回memcached
JMX管理&监控

该方案的不足之处:
memcache支持的数据结构比较单一
memcache的内存必须足够大,否则会出现用户session从Cache中被清除
需要定期的刷新缓存
服务器故障时,存在于内存的memcache数据将会丢失

为了解决基于memcache中存在的不足,故提出了下面的一种解决方案:

三、基于redis缓存的session共享
结合上面的分析后,由redis负责session数据的存储,而我们自己实现的session manager将负责session生命周期的管理。利用 redis 自身的key过期时间机制,我们不再需要定期刷新和做其他额外的处理。

截止到2015-09-20 前是不支持Tomcat8的,开源Git 地址:https://github.com/jcoleman/tomcat-redis-session-manager
因为我们使用redis 来存储Session,所以前提是redis已经安装和配置完成。(本文不进行redis 的安装配置说明)
使用步骤:

1、将 tomcat-redis-session-manager-1.2.jar 、jedis-2.6.1.jar、commons-pool2-2.2.jar 三个jar包拷贝到tomcat7/lib中。
2、在Tomcat 的conf/context.xml 文件里增加如下内容:

<Valve className="com.orangefunction.tomcat.redissessions.RedisSessionHandlerValve" />
<Manager className="com.orangefunction.tomcat.redissessions.RedisSessionManager"
                   host="localhost" <!-- 可选,默认是"localhost" -->
                   port="6379" <!-- 可选,默认是 "6379" -->
                   database="0" <!-- 可选,默认是 "0" -->
                   maxInactiveInterval="60" <!-- 可选,默认是 "60" (单位:秒)--> />

3、重启Tomcat7,到redis 中查看session_id,如下:

127.0.0.1:6379> keys WJ*
1) "WJSESSIONID:6D5B0E0FD89E3A170B8BC5B8C112D3FD"
2) "WJSESSIONID:9546B26D78C99E8F0BF785535E319271"
3) "WJSESSIONID:839A35CFE17E900A81F50D629C104D2F"
4) "WJSESSIONID:1C287C797CF00C82BBBF37A617A3B55C"
5) "WJSESSIONID:FA2822C5021139641760754242F73393"
6) "WJSESSIONID:E904369E5B24D39B4E25515D50650EA6"
127.0.0.1:6379>

这里进行一下特殊说明:
git 开源项目是直接将SESSIONID作为key存储到redis中的,如下所示:

1) "6D5B0E0FD89E3A170B8BC5B8C112D3FD"
2) "9546B26D78C99E8F0BF785535E319271"
3) "839A35CFE17E900A81F50D629C104D2F"
4) "1C287C797CF00C82BBBF37A617A3B55C"
5) "FA2822C5021139641760754242F73393"
6) "E904369E5B24D39B4E25515D50650EA6"

我对该项目做了一点修改。
修改原因包括几点:
1、项目也有使用redis 做其他数据存储,直接使用这样的key存储到redis中,直观上无法区分哪些key是用来做session共享用的。
2、项目包括好几个服务(web、wap、cms),每个服务都需要做负载均衡session共享,这样以来无法区分哪些session是属于哪个服务的。
3、很难统计每个服务的在线用户数。

我在集群部署中我的每个服务都有不同的sessionCookieName(web = WJSESSIONID、wap = MJSESSIONID、cms = CMSJSESSIONID)
不知道怎么配置的,这里简单说一下,直接在tomcat7/conf/server.xml 的最下面的Context中增加 sessionCookieName 配置即可:

<Context docBase="F:\workspace\web" path="" reloadable="false" sessionCookieName="WJSESSIONID" />

我修改后的项目已经共享到:http://download.csdn.net/detail/catoop/9122857 (项目是一个maven项目)
其中 tomcat-redis-session-manager\target\tomcat-redis-session-manager-1.2.jar 可以直接使用。

时间: 2024-10-10 06:35:50

Tomcat7基于Redis的Session共享实战二的相关文章

项目分布式部署那些事(1):ONS消息队列、基于Redis的Session共享,开源共享

因业务发展需要现在的系统不足以支撑现在的用户量,于是我们在一周之前着手项目的性能优化与分布式部署的相关动作. 概况 现在的系统是基于RabbitHub(一套开源的开发时框架)和Rabbit.WeiXin(开源的微信开发SDK)开发的一款微信应用类系统,主要业务是围绕当下流行的微信元素,如:微官网.微商城.微分销.营销活动.会员卡等. 关于RabbitHub详情请戳: .NET 平台下的插件化开发内核(Rabbit Kernel) RabbitHub开源情况及计划 关于Rabbit.WeiXin详

.Net分布式架构(二):基于Redis的Session共享

一:Session简介 Session是什么呢?简单来说就是服务器给客户端的一个编号.当一台web服务器运行时,可能有若干个用户浏览正在运正在这台服务器上的网站.当每个用户首次与这台web服务器建立连接时,他就与这个服务器建立了一个Session,同时服务器会自动为其分配一个SessionID,用以标识这个用户的唯一身份.这个SessionID是由web服务器随机产生的一个由24个字符组成的字符串,我们会在下面的实验中见到它的实际样子. 二:Asp.Net中Session的集中模式和配置 (1)

LNMT群集基于Redis实现Session共享

前言:为了使web能适应大规模的访问,需要实现应用的集群部署.集群最有效的方案就是负载均衡,而实现负载均衡用户每一个请求都有可能被分配到不固定的服务器上,这样我们首先要解决session的统一来保证无论用户的请求被转发到哪个服务器上都能保证用户的正常用,也就是需要实现session的共享机制. 在集群系统下实现session统一的有如下几种方案:1.请求精确定位:sessionsticky,例如基于访问ip的hash策略,即当前用户的请求都集中定位到一台服务器中,这样单台服务器保存了用户的ses

分布式中使用Redis实现Session共享(二)

上一篇介绍了一些redis的安装及使用步骤,本篇开始将介绍redis的实际应用场景,先从最常见的session开始,刚好也重新学习一遍session的实现原理.在阅读之前假设你已经会使用nginx+iis实现负载均衡搭建负载均衡站点了,这里我们会搭建两个站点来验证redis实现的session是否能共享. 阅读目录 Session实现原理 session共享实现方案 问题拓展 总结 回到顶部 Session实现原理 session和cookie是我们做web开发中常用到的两个对象,它们之间会不会

spring boot + redis 实现session共享

这次带来的是spring boot + redis 实现session共享的教程. 在spring boot的文档中,告诉我们添加@EnableRedisHttpSession来开启spring session支持,配置如下: @Configuration @EnableRedisHttpSession public class RedisSessionConfig { } 而@EnableRedisHttpSession这个注解是由spring-session-data-redis提供的,所以

nginx+redis实现session共享 .NET分布式架构

上两篇文件介绍了如何安装和封装redis 本篇主要是记录下怎么实现 nginx+redis实现session共享 目前session问题点 又爱又恨的Session 刚接触程序开发的人一定爱死Session了,因为Session让Http从无状态变成有状态了,页面之间传值.用户相关信息.一些不变的数据.甚至于查出来的DataTable也可以放进去,取值的时候只需要Session[Key]即可,真是方便极了.Session真是个利器,人挡杀人佛挡杀佛,但任何事物被封为利器基本也是双刃剑,Sessi

使用 Redis 实现 Session 共享

1    第4-3课:使用 Redis 实现 Session 共享 在微服务架构中,往往由多个微服务共同支撑前端请求,如果涉及到用户状态就需要考虑分布式 Session 管理问题,比如用户登录请求分发在服务器 A,用户购买请求分发到了服务器 B, 那么服务器就必须可以获取到用户的登录信息,否则就会影响正常交易.因此,在分布式架构或微服务架构下,必须保证一个应用服务器上保存 Session 后,其他应用服务器可以同步或共享这个 Session. 目前主流的分布式 Session 管理有两种方案.

springboot+redis实现session共享

1.场景描述 因项目访问压力有点大,需要做负载均衡,但是登录使用的是公司统一提供的单点登录系统,需要做session共享,否则假如在A机器登录成功,在B机器上操作就会存在用户未登录情况. 2. 解决方案 因项目是springboot项目,采用Springboot+Springsession+Redis来实现session共享. 2.1 pom.xml文件 <dependency> <groupId>org.springframework.boot</groupId> &

Spring Boot 多站点利用 Redis 实现 Session 共享

如何在不同站点(web服务进程)之间共享会话 Session 呢,原理很简单,就是把这个 Session 独立存储在一个地方,所有的站点都从这个地方读取 Session. 通常我们使用 Redis 来解决这个问题 Spring Boot 2.1.8 Redis 5.0.3 本项目源码 github 下载 本章解决前面文章 Spring Boot 利用 nginx 实现生产环境的伪热更新 产生的session共享问题. 1 Redis 准备 本示例使用 Redis 5.0.3 操作系统为 Mac