使用Spring Session做分布式会话管理

在Web项目开发中,会话管理是一个很重要的部分,用于存储与用户相关的数据。通常是由符合session规范的容器来负责存储管理,也就是一旦容器关闭,重启会导致会话失效。因此打造一个高可用性的系统,必须将session管理从容器中独立出来。而这实现方案有很多种,下面简单介绍下:

  第一种是使用容器扩展来实现,大家比较容易接受的是通过容器插件来实现,比如基于Tomcat的tomcat-redis-session-manager,基于Jetty的jetty-session-redis等等。好处是对项目来说是透明的,无需改动代码。不过前者目前还不支持Tomcat 8,或者说不太完善。个人觉得由于过于依赖容器,一旦容器升级或者更换意味着又得从新来过。并且代码不在项目中,对开发者来说维护也是个问题。

  第二种是自己写一套会话管理的工具类,包括Session管理和Cookie管理,在需要使用会话的时候都从自己的工具类中获取,而工具类后端存储可以放到Redis中。很显然这个方案灵活性最大,但开发需要一些额外的时间。并且系统中存在两套Session方案,很容易弄错而导致取不到数据。

  第三种是使用框架的会话管理工具,也就是本文要说的spring-session,可以理解是替换了Servlet那一套会话管理,既不依赖容器,又不需要改动代码,并且是用了spring-data-redis那一套连接池,可以说是最完美的解决方案。当然,前提是项目要使用Spring Framework才行。

  这里简单记录下整合的过程:

  如果项目之前没有整合过spring-data-redis的话,这一步需要先做,在maven中添加这两个依赖:

<dependency>

    <groupId>org.springframework.data</groupId>

    <artifactId>spring-data-redis</artifactId>

    <version>1.5.2.RELEASE</version>

</dependency>

<dependency>

    <groupId>org.springframework.session</groupId>

    <artifactId>spring-session</artifactId>

    <version>1.0.2.RELEASE</version>

</dependency>

  再在applicationContext.xml中添加以下bean,用于定义redis的连接池和初始化redis模版操作类,自行替换其中的相关变量。

<!-- redis -->

<bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">

</bean>

<bean id="jedisConnectionFactory"

    class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">

    <property name="hostName" value="${redis.host}" />

    <property name="port" value="${redis.port}" />

    <property name="password" value="${redis.pass}" />

    <property name="timeout" value="${redis.timeout}" />

    <property name="poolConfig" ref="jedisPoolConfig" />

    <property name="usePool" value="true" />

</bean>

<bean id="redisTemplate" class="org.springframework.data.redis.core.StringRedisTemplate">

    <property name="connectionFactory" ref="jedisConnectionFactory" />

</bean>

<!-- 将session放入redis -->

<bean id="redisHttpSessionConfiguration"

class="org.springframework.session.data.redis.config.annotation.web.http.RedisHttpSessionConfiguration">

    <property name="maxInactiveIntervalInSeconds" value="1800" />

</bean>

  这里前面几个bean都是操作redis时候使用的,最后一个bean才是spring-session需要用到的,其中的id可以不写或者保持不变,这也是一个约定优先配置的体现。这个bean中又会自动产生多个bean,用于相关操作,极大的简化了我们的配置项。其中有个比较重要的是springSessionRepositoryFilter,它将在下面的代理filter中被调用到。maxInactiveIntervalInSeconds表示超时时间,默认是1800秒。写上述配置的时候我个人习惯采用xml来定义,官方文档中有采用注解来声明一个配置类。

  然后是在web.xml中添加一个session代理filter,通过这个filter来包装Servlet的getSession()。需要注意的是这个filter需要放在所有filter链最前面。

<!-- delegatingFilterProxy -->

<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>

  这样便配置完毕了,需要注意的是,spring-session要求Redis Server版本不低于2.8。

  验证:使用redis-cli就可以查看到session key了,且浏览器Cookie中的jsessionid已经替换为session。

127.0.0.1:6379> KEYS *

1) "spring:session:expirations:1440922740000"

2) "spring:session:sessions:35b48cb4-62f8-440c-afac-9c7e3cfe98d3"

时间: 2024-12-28 05:40:07

使用Spring Session做分布式会话管理的相关文章

Spring多数据源分布式事务管理/springmvc+spring+atomikos[jta]+druid+mybatis

项目进行读写分离及分库分表,在一个业务中,在一个事务中处理时候将切换多个数据源,需要保证同一事务多个数据源数据的一致性.此处使用atomikos来实现:最后附源码: 1:spring3.0之后不再支持jtom[jta]了,第三方开源软件atomikos(http://www.atomikos.com/)来实现. 2:org.springframework.transaction.jta.JotmFactoryBean类,spring-tx-2.5.6.jar中有此类,spring-tx-3.0.

如何使用Spring Session实现分布式Session管理

Spring Session作为Spring社区官方推荐的一个比较简单快速的Java Web分布式session解决方案,帮我们搞定了长期以来比较蛋疼的session分布式的问题. Spring Session解决的基本思路很简单,即将用户的session信息全部存放到一个redis数据库中,所有的session都从这个数据库拿.由于redis是一个内存数据库,数据信息读写是非常快速的.如此一来,多个Tomcat,共用一个redis数据库,即实现了session的共享问题. 鉴于目前很少看到Sp

Spring Session解决分布式Session问题的实现原理

使用Spring Session和Redis解决分布式Session跨域共享问题 上一篇介绍了如何使用spring Session和Redis解决分布式Session跨域共享问题,介绍了一个简单的案例,下边就学习一下Spring Session的实现原理. 注:以下步骤是基于XML的方式实现 Spring Session的代码讲解! 先从web.xml文件说起 我们知道Tomcat再启动的时候首先会去加载web.xml 文件,Tomcat启动的时候web.xml被加载的顺序:context-pa

大型网站之分布式会话管理

随着网站的功能和用户越来越多,单机器服务部署的Web应用已经不能再支持了.这时候就需要优化或调整目前的架构,具体怎么优化,或先优化哪部分,这取决于网站的具体情况, 并非总是一个套路. 如根据使用情况得知,数据库压力大,则就可以先设施读写分离,分库分表,是垂直划分(可以简单的理解为按业务功能划分), 还是水平划分(如用户表数据量很多,就可以按一定的规则分表设计,表结构仍然是相同的).如Web应用服务器压力大,可以增加一台服务部署应用, 即从单台服务变为集群.变为集群后,用户访问网站,到底是选择哪一

session management会话管理的原理

web请求与响应基于http,而http是无状态协议.所以我们为了跨越多个请求保留用户的状态,需要利用某种工具帮助我们记录与识别每一次请求及请求的其他信息.举个栗子,我们在淘宝购物的时候,首先添加了一本<C++ primer>进入购物车,然后我们又继续去搜索<thinking in java>,继续添加购物车,这时购物车应该有两本书.但如果我们不采取session management会话管理的话,基于http无状态协议,我们在第二次向购物车发出添加请求时,他是无法知道我们第一次添

详解 Spring Session 架构与设计

前言 开始进行 Web 开发时,您可能在使用 Session 时会碰到 Cookie 和 LocalStorage,被它们所干扰.因为他们都可以存储数据,有过期时间,不需要在使用时重新请求.您还会遇到这样的情况,Web 容器(例如 Tomcat.Jetty)包含 Session 的实现,当服务器重启之后,之前的登录状态会失效需要重新登录. 为什么需要 Spring SessionHTTP 协议 我们先从 HTTP 协议说起.HTTP 协议有个特点,是无状态的,意味着请求与请求是没有关系的.早期的

Shiro 简介(认证、授权、加密、会话管理、与 Web 集成、缓存等)

https://www.w3cschool.cn/shiro/ Shiro 简介 简介 Apache Shiro 是 Java 的一个安全框架.目前,使用 Apache Shiro 的人越来越多,因为它相当简单,对比 Spring Security,可能没有 Spring Security 做的功能强大,但是在实际工作时可能并不需要那么复杂的东西,所以使用小而简单的 Shiro 就足够了.对于它俩到底哪个好,这个不必纠结,能更简单的解决项目问题就好了. 本教程只介绍基本的 Shiro 使用,不会

常用会话管理方式

会话管理方式 http是无状态的,这就意味着客户端即使第一次请求已经验证了身份,但是第二次请求的时候服务器仅通过http连接并不能知道是那个用户.但是我们是需要状态管理的,比如用户登录了才能做一些其它操作,这就需要我们进行会话管理. 这里主要讲两种管理方式 基于session的管理方式 基于ticket管理方式 1. 基于session的方法 客户端送第一次请求后,服务端在服务器创建session信息,并将sessionid传送给浏览器 第一次请求 第一请求并没有带cookie信息,服务器返回s

Java中的会话管理——HttpServlet,Cookies,URL Rewriting(译)

参考谷歌翻译,关键字直接使用英文,原文地址:http://www.journaldev.com/1907/java-session-management-servlet-httpsession-url-rewriting Java Web应用程序中的会话管理(Session Management)是一个非常有趣的话题.Java Servlet中的会话通过不同的方式进行管理,例如Cookie,HttpSession API,URL重写等. 这是Java Web应用程序系列教程中的第三篇文章,您可能