Spring Session+Spring Data Redis 解决分布式系统架构中 Session 共享问题
2017-02-04 15:55
756 查看
如题所示,在分布式系统架构中需要解决的一个很重要的问题就是——如何保证各个应用节点之间的Session共享。其实有一个很好的解决办法就是在redis、memcached等组件中独立存储所有应用节点的Session,以达到各个应用节点之间的Session共享的目的
Spring Session提供了一种独立于应用服务器的方案,这种方案能够在Servlet规范之内配置可插拔的session数据存储,不依赖于任何应用服务器的特定API。这就意味着Spring Session能够用于实现了servlet规范的所有应用服务器之中(Tomcat、Jetty、 WebSphere、WebLogic、JBoss等),它能够非常便利地在所有应用服务器中以完全相同的方式进行配置。同时我们还可以选择任意最适应需求的外部session数据存储方式
Spring Session为企业级Java应用的session管理带来了革新,使得以下的功能更加容易实现:
编写可水平扩展的原生云应用
将session所保存的状态保存到特定的外部session存储中,如Redis或Apache Geode中,它们能够以独立于应用服务器的方式提供高质量的集群
当用户使用WebSocket发送请求的时候,能够保持HttpSession处于活跃状态
在非Web请求的处理代码中,能够访问session数据,比如在JMS消息的处理代码中
支持每个浏览器上使用多个session,从而能够很容易地构建更加丰富的终端用户体验
控制session id如何在客户端和服务器之间进行交换,这样的话就能很容易地编写Restful API,因为它可以从HTTP 头信息中获取session id,而不必再依赖于cookie
需要说明的很重要的一点就是,Spring Session的核心项目并不依赖于Spring框架,所以,我们甚至能够将其应用于不使用Spring框架的项目中
其实,我们想要在项目中使用Spring Session需要做的工作并不多,只需要做到以下几步即可:
在项目的spring-data-redis相关配置中添加以下配置:
完整的context_redis_cluster.xml文件如下:
注:对应的属性文件是:
在web.xml中添加以下filter:
注:需要将这个filter放在第一位,其他的如编码、shiro等filter需要放在这之后
到此,Spring Session和Spring Data Redis就整合到项目中了
从上图可以发现,登录之后的用户对象已经保存到redis集群中了。接着还可以测试将同样的项目发布到其他端口的tomcat上,在同一浏览器上访问需要登录认证之后才能访问的页面,看看是否能够直接访问。如果能够直接访问而不是重定向到登录页面,则说明已经达到session共享的效果了
Spring Session提供了一种独立于应用服务器的方案,这种方案能够在Servlet规范之内配置可插拔的session数据存储,不依赖于任何应用服务器的特定API。这就意味着Spring Session能够用于实现了servlet规范的所有应用服务器之中(Tomcat、Jetty、 WebSphere、WebLogic、JBoss等),它能够非常便利地在所有应用服务器中以完全相同的方式进行配置。同时我们还可以选择任意最适应需求的外部session数据存储方式
Spring Session为企业级Java应用的session管理带来了革新,使得以下的功能更加容易实现:
编写可水平扩展的原生云应用
将session所保存的状态保存到特定的外部session存储中,如Redis或Apache Geode中,它们能够以独立于应用服务器的方式提供高质量的集群
当用户使用WebSocket发送请求的时候,能够保持HttpSession处于活跃状态
在非Web请求的处理代码中,能够访问session数据,比如在JMS消息的处理代码中
支持每个浏览器上使用多个session,从而能够很容易地构建更加丰富的终端用户体验
控制session id如何在客户端和服务器之间进行交换,这样的话就能很容易地编写Restful API,因为它可以从HTTP 头信息中获取session id,而不必再依赖于cookie
需要说明的很重要的一点就是,Spring Session的核心项目并不依赖于Spring框架,所以,我们甚至能够将其应用于不使用Spring框架的项目中
二 代码示例
其实,我们想要在项目中使用Spring Session需要做的工作并不多,只需要做到以下几步即可:(1)引入相关jar包:
这里需要引入Spring Session和Spring Data Redis相关的依赖jar包。可以自行从maven仓库下载,也可以参考我使用的jar包:http://down.51cto.com/data/2281837
(2)修改spring-data-redis相关配置:
在项目的spring-data-redis相关配置中添加以下配置:<bean id="redisHttpSessionConfiguration" class="org.springframework.session.data.redis.config.annotation.web.http.RedisHttpSessionConfiguration"> <!--超时时间,默认1800秒--> <property name="maxInactiveIntervalInSeconds" value="1800" /> </bean>
完整的context_redis_cluster.xml文件如下:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:jee="http://www.springframework.org/schema/jee" xmlns:p="http://www.springframework.org/schema/p" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-4.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd"> <description>spring-data-redis-cluster</description> <!-- 配置Cluster --> <bean id="redisClusterConfiguration" class="org.springframework.data.redis.connection.RedisClusterConfiguration"> <property name="maxRedirects" value="${redis.cluster.maxRedirects}" /> <!-- 节点配置 --> <property name="clusterNodes"> <set> <bean class="org.springframework.data.redis.connection.RedisClusterNode"> <constructor-arg name="host" value="${redis.cluster.host1}" /> <constructor-arg name="port" value="${redis.cluster.port1}" /> </bean> <bean class="org.springframework.data.redis.connection.RedisClusterNode"> <constructor-arg name="host" value="${redis.cluster.host2}" /> <constructor-arg name="port" value="${redis.cluster.port2}" /> </bean> <bean class="org.springframework.data.redis.connection.RedisClusterNode"> <constructor-arg name="host" value="${redis.cluster.host3}" /> <constructor-arg name="port" value="${redis.cluster.port3}" /> </bean> <bean class="org.springframework.data.redis.connection.RedisClusterNode"> <constructor-arg name="host" value="${redis.cluster.host4}" /> <constructor-arg name="port" value="${redis.cluster.port4}" /> </bean> <bean class="org.springframework.data.redis.connection.RedisClusterNode"> <constructor-arg name="host" value="${redis.cluster.host5}" /> <constructor-arg name="port" value="${redis.cluster.port5}" /> </bean> <bean class="org.springframework.data.redis.connection.RedisClusterNode"> <constructor-arg name="host" value="${redis.cluster.host6}" /> <constructor-arg name="port" value="${redis.cluster.port6}" /> </bean> </set> </property> </bean> <bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig"> <property name="maxTotal" value="${redis.cluster.jedisPoolConfig.maxTotal}" /> <property name="maxIdle" value="${redis.cluster.jedisPoolConfig.maxIdle}" /> <property name="maxWaitMillis" value="${redis.cluster.jedisPoolConfig.maxWaitMillis}" /> <property name="testOnBorrow" value="${redis.cluster.jedisPoolConfig.testOnBorrow}" /> </bean> <bean id="jedisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"> <constructor-arg ref="redisClusterConfiguration" /> <constructor-arg ref="jedisPoolConfig" /> <property name="password" value="${redis.cluster.jedisConnectionFactory.password}" /> </bean> <bean id="stringRedisSerializer" class="org.springframework.data.redis.serializer.StringRedisSerializer" /> <bean id="jdkSerializer" class="org.springframework.data.redis.serializer.JdkSerializationRedisSerializer" /> <bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate" p:connection-factory-ref="jedisConnectionFactory"> <!-- 序列化方法 --> <property name="keySerializer" ref="stringRedisSerializer" /> <property name="hashKeySerializer" ref="stringRedisSerializer" /> <property name="valueSerializer" ref="jdkSerializer" /> <property name="hashValueSerializer" ref="jdkSerializer" /> </bean> <bean id="stringRedisTemplate" class="org.springframework.data.redis.core.StringRedisTemplate" p:connection-factory-ref="jedisConnectionFactory" /> <bean id="redisHttpSessionConfiguration" class="org.springframework.session.data.redis.config.annotation.web.http.RedisHttpSessionConfiguration"> <!--超时时间,默认1800秒--> <property name="maxInactiveIntervalInSeconds" value="1800" /> </bean> </beans>
注:对应的属性文件是:
#Redis Cluster redis.cluster.maxRedirects=3 redis.cluster.host1=192.168.1.30 redis.cluster.port1=7000 redis.cluster.host2=192.168.1.30 redis.cluster.port2=7001 redis.cluster.host3=192.168.1.30 redis.cluster.port3=7002 redis.cluster.host4=192.168.1.224 redis.cluster.port4=7003 redis.cluster.host5=192.168.1.224 redis.cluster.port5=7004 redis.cluster.host6=192.168.1.224 redis.cluster.port6=7005 #JedisPoolConfig redis.cluster.jedisPoolConfig.maxTotal=1024 redis.cluster.jedisPoolConfig.maxIdle=20 redis.cluster.jedisPoolConfig.maxWaitMillis=100000 redis.cluster.jedisPoolConfig.testOnBorrow=true #JedisConnectionFactory redis.cluster.jedisConnectionFactory.password=admin
(3)修改web.xml:
在web.xml中添加以下filter:<!-- Spring Session配置 --> <filter> <filter-name>springSessionRepositoryFilter</filter-name> <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class> </filter> <filter-mapping> <filter-name>springSessionRepositoryFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
注:需要将这个filter放在第一位,其他的如编码、shiro等filter需要放在这之后
到此,Spring Session和Spring Data Redis就整合到项目中了
(4)测试:
运行项目后,可以发现生成了一个名为“SESSION”的cookie。接着在我们登录之后,可以通过其cookie值在redis上取得保存的对应的session对象。如下图所示:从上图可以发现,登录之后的用户对象已经保存到redis集群中了。接着还可以测试将同样的项目发布到其他端口的tomcat上,在同一浏览器上访问需要登录认证之后才能访问的页面,看看是否能够直接访问。如果能够直接访问而不是重定向到登录页面,则说明已经达到session共享的效果了
相关文章推荐
- spring-session,利用redis存储session,解决集群共享session的问题
- spring boot学习5之session+redis解决session共享问题
- laravel5.3使用redis管理session解决session共享问题
- 基于Spring session data redis的session共享
- spring boot--整合spring session实现session共享以及cookie丢失问题解决
- Redis+Shiro+Spring-data-redis,共享Session
- 解决spring+springMVC+Hibernate+spring-data-jpa懒加载No session问题
- spring boot学习5之session+redis解决session共享问题
- spring-session-data-redis使用redis共享session
- SpringDataJpa -- NoSession问题分析和解决
- 解决了Hibernate+Spring+Struts架构使用OpenSessionInView的问题
- jedis,spring-redis-data 整合使用,版本问题异常以及解决。
- 使用redis解决tomcat6在nginx负载下多节点共享session问题
- Spring整合Spring Session,用redis解决分布式session共享问题
- 【集群部署】redis解决session共享问题
- session理论以及解决分布式系统下的session共享问题
- SpringCloud实现Redis在各个微服务的Session共享问题
- spring-session和redis解决spring cloud中session不一致性问题
- spring boot session Redis共享方案和一些疑惑的解决
- J2EE通用后台管理系统 springmvc+mybatis+nginx+shiro+redis架构的session共享