高性能开发(2) Redis缓存实现分布式session共享(一)
来源:互联网 发布:涵洞软件 编辑:程序博客网 时间:2024/05/21 14:02
在讲解redis分布式session共享之前,我们先聊聊tomcat中session管理机制,
包括:请求过程中session操作,sessionid解析过程,servlet获取session流程,以及tomca中session的管理机制。
一、Tomcat session管理机制
1.1 请求过程中的session操作:
在请求过程中首先要解析请求中的sessionid信息,然后将sessionid存储到request的参数列表中。
然后再从request获取session的时候,如果存在sessionid那么就根据id从session池中获取session,
如果sessionid不存在或者sesssion失效,那么则新建session并且将session信息放入session池,供下次使用。
1.2 sessionid解析过程(web工程引入tomcat jar包可debug调试):
用户发送一个http请求传递给Http11Processor,经由Http11Processor解析封装在org.apache.coyote.Request然后传递给CoyoteAdapter,CoyoteAdapter是一个适配器,将coyote框架封装的org.apache.coyote.Request适配给org.apache.catalina.connector.Request,转换完之后会调用parsePathParameters方法区解析路径参数中的cookie信息,
先尝试从url中解析出sessionid,然后会调用parseSessionCookiesId,这个就是从cookie中解析sessionid存在request。
解析到sessionid就放到了request里面,解析sessionid的逻辑就ok了。
1.3 servlet获取session的流程:
servlet通过request获取session的时候,其实调用的是HttpServletRequest(其实是RequestFacade,封装了Request的一个门面),然后RequestFacade会调用真是得Request的getSession方法。Request具体逻辑是调用Context容器的getManger方法获取session管理器,然后如果sessionid如果被解析出来了,那么则会调用findSession方法从session对象池中获取对应的session,反之如果sessionid不存在,则需要重新创建一个session,并放入session对象池中。
1.4 session管理机制:
session管理器组件负责管理session对象,eg:创建和销毁session对象
(1)Manager:定义了关联到某一个容器的用来管理session池的基本接口。
(2)ManagerBase:实现了Manager接口,该类提供了Session管理器的常见功能的实现。
(3)StandardManager:继承自ManagerBase,tomcat的默认Session管理器(不指定配置,默认使用这个),是tomcat处理session的非集群实现(也就说是单机版的),tomcat关闭时,内存session信息会持久化到磁盘保存为SESSION.ser,再次启动时恢复。
(4)PersistentManagerBase:继承自ManagerBase,实现了和定义了session管理器持久化的基础功能。
(5) PersistentManager:继承自PersistentManagerBase,主要实现的功能是会把空闲的会话对象(通过设定超时时间)交换到磁盘上。
(6)ClusterManager:实现了Manager接口,通过类名应该能猜到,这个就是管理集群session的管理器和上面那个StandardManager单机版的session管理器是相对的概念。这个类定义类集群间session的复制共享接口。
(7)ClusterManagerBase:实现了ClusterManager接口,继承自ManagerBase。该类实现了session复制的基本操作。
(8)BackupManager:继承自ClusterManagerBase, 集群间session复制策略的一种实现,会话数据只有一个备份节点,这个备份节点的位置集群中所有节点都可见。这种设计使它有个优势就是支持异构部署。
(9)DeltaManager:继承自ClusterManagerBase,集群建session复制策略的一种实现,和BackupManager不同的是,会话数据会复制到集群中所有的成员节点,这也就要求集群中所有节点必须同构,必须部署相同的应用。
(1)Manager:定义了关联到某一个容器的用来管理session池的基本接口。
(2)ManagerBase:实现了Manager接口,该类提供了Session管理器的常见功能的实现。
(3)StandardManager:继承自ManagerBase,tomcat的默认Session管理器(不指定配置,默认使用这个),是tomcat处理session的非集群实现(也就说是单机版的),tomcat关闭时,内存session信息会持久化到磁盘保存为SESSION.ser,再次启动时恢复。
(4)PersistentManagerBase:继承自ManagerBase,实现了和定义了session管理器持久化的基础功能。
(5) PersistentManager:继承自PersistentManagerBase,主要实现的功能是会把空闲的会话对象(通过设定超时时间)交换到磁盘上。
(6)ClusterManager:实现了Manager接口,通过类名应该能猜到,这个就是管理集群session的管理器和上面那个StandardManager单机版的session管理器是相对的概念。这个类定义类集群间session的复制共享接口。
(7)ClusterManagerBase:实现了ClusterManager接口,继承自ManagerBase。该类实现了session复制的基本操作。
(8)BackupManager:继承自ClusterManagerBase, 集群间session复制策略的一种实现,会话数据只有一个备份节点,这个备份节点的位置集群中所有节点都可见。这种设计使它有个优势就是支持异构部署。
(9)DeltaManager:继承自ClusterManagerBase,集群建session复制策略的一种实现,和BackupManager不同的是,会话数据会复制到集群中所有的成员节点,这也就要求集群中所有节点必须同构,必须部署相同的应用。
二、Redis分布式session配置
如上图,多实例下可以使用redis实现分布式session管理,客户端请求,经过负载均衡分发至tomcat实例,再经过session管理,实现session在redis中存取。配置redis主从集群,主redis数据热备份至从redis,当主redis宕机了,系统自动切换至从redis,从而保证系统缓存方面高可用。
1.redis配置
可以使用spring-redis.xml作为redis配置文件名,首先配置redis缓存池:
可以使用spring-redis.xml作为redis配置文件名,首先配置redis缓存池:
<bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig"> <property name="maxTotal" value="${redis.pool.maxTotal}"/> <property name="maxIdle" value="${redis.pool.maxIdle}"/> <property name="maxWaitMillis" value="${redis.pool.maxWaitMillis}"/> <property name="testOnBorrow" value="${redis.pool.testOnBorrow}"/></bean>再配置redis模板引擎redisTemplat:
<bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate"> <property name="connectionFactory"> <bean class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory" p:hostName="${redis.host.business}" p:port="${redis.port.business}" p:database="1" p:password="${redis.password.business}" p:poolConfig-ref="jedisPoolConfig" /> </property> <property name="defaultSerializer" ref="stringRedisSerializer" /> <property name="keySerializer" ref="stringRedisSerializer" /> <property name="valueSerializer" ref="jdkSerializationRedisSerializer" /> <property name="hashValueSerializer" ref="jdkSerializationRedisSerializer" /></bean>2.配置分布式session过滤器
<filter> <filter-name>springSessionFilter</filter-name> <filterclass>org.springframework.web.filter.DelegatingFilterProx</filter-class> <init-param> <param-name>targetBeanName</param-name> <param-value>springSession</param-value> </init-param></filter>web.xml中配置分布式session过滤器,初始化bean name是springSession;将需要用到分布式session请求配置至过滤器中,
代码如下:
配置分布式session管理bean(SessionRepositoryFilter.java),经过第二步过滤器的请求,都会经过这个管理bean,配置SessionRepositoryFilter.java默认构造函数是redis session操作仓RedisOperationsSessionRepository.java。
<filter-mapping> <filter-name>springSessionFilter</filter-name> <url-pattern>/shoppingcart/*</url-pattern></filter-mapping><filter-mapping> <filter-name>springSessionFilter</filter-name> <url-pattern>/my/*</url-pattern></filter-mapping>3.redis session配置
配置分布式session管理bean(SessionRepositoryFilter.java),经过第二步过滤器的请求,都会经过这个管理bean,配置SessionRepositoryFilter.java默认构造函数是redis session操作仓RedisOperationsSessionRepository.java。
<bean id="springSession" class="com.bbkmobile.iqoo.vivoshop.common.session.SessionRepositoryFilter"> <constructor-arg> <bean class="org.springframework.session.data.redis.RedisOperationsSessionRepository"> <constructor-arg> <bean class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory" p:port="${redis.port.session}"p:hostName="${redis.host.session}" p:password="${redis.password.session}" p:poolConfigref="jedisPoolConfig" /> </constructor-arg> </bean> </constructor-arg></bean>
redis如何实现session分布式存取在下一节介绍。
三、分布式session请求流程
上一节介绍了spring mvc框架下redis session系统配置管理,下面我将会redis中session请求流程进行介绍。
如上一节所述,经过过滤器的请求,进入SessionRepositoryFilter,其默认使用RedisOperationsSessionRepository作为构造函数参数。
wrappedRequest.commitSession();
commitSession方法中,
sessionRepository.save(session)
调用RedisOperationsSessionRepository的save()方法,将session以key value形式存放到redis中。
获取session时,SessionRepositoryFilter调用getSession()方法,方法内部
获取session时,SessionRepositoryFilter调用getSession()方法,方法内部
S
session = sessionRepository.getSession(requestedSessionId);
调用RedisOperationsSessionRepository的getSession()方法,从redis中获取session。
具体RedisOperationsSessionRepository如果将session存取值redis,不再讲述,可以查阅源码。
0 0
- 高性能开发(2) Redis缓存实现分布式session共享(一)
- redis实现分布式session共享
- redis实现分布式session共享
- 分布式中使用Redis实现Session共享(一)
- 分布式中使用Redis实现Session共享(一)
- Spring Session + Redis实现分布式Session共享
- Spring Session + Redis实现分布式Session共享
- Spring Session + Redis实现分布式Session共享
- Spring Session + Redis实现分布式Session共享
- Spring Session + Redis实现分布式Session共享
- Spring Session + Redis实现分布式Session共享
- Spring Session + Redis实现分布式Session共享
- Spring Session + Redis实现分布式Session共享
- Spring Session + Redis实现分布式Session共享
- Spring Session + Redis实现分布式Session共享
- Spring Session + Redis实现分布式Session共享
- Redis实现分布式session功能的共享
- 分布式中使用Redis实现Session共享
- 23中设计模式之_状态模式
- 图解HTTP读书笔记
- 注重科技积累 三星手机以创新赢得地位与利润
- Linux 数据库
- 命令行中文乱码问题
- 高性能开发(2) Redis缓存实现分布式session共享(一)
- 直接拿来用!最火的Android开源项目
- PTA-整数分解为若干项之和
- Eclipse build errors
- 方便好使的java.util.Properties类
- MFC OCX开发笔记
- URL和URI的区别详谈
- RxJava + RxAndroid学习
- Linux 学习记录一