使用Spring Session和Redis解决分布式Session跨域共享问题

原创 2017-02-27 徐刘根 Java后端技术

前言

对于分布式使用Nginx+Tomcat实现负载均衡,最常用的均衡算法有IP_Hash、轮训、根据权重、随机等。不管对于哪一种负载均衡算法,由于Nginx对不同的请求分发到某一个Tomcat,Tomcat在运行的时候分别是不同的容器里,因此会出现session不同步或者丢失的问题。

实际上实现Session共享的方案很多,其中一种常用的就是使用Tomcat、Jetty等服务器提供的Session共享功能,将Session的内容统一存储在一个数据库(如MySQL)或缓存(如Redis)中。

在以前写的一篇文章中:

使用Redis存储Nginx+Tomcat负载均衡集群的Session

这一篇文章中已经学习了一下,如何使用 tomcat-redis-session-manager 开源项目解决分布式session跨域的问题,他的主要思想是利用Servlet容器提供的插件功能,自定义HttpSession的创建和管理策略,并通过配置的方式替换掉默认的策略。tomcat-redis-session-manager重写了Tomcat的org.apache.catalina.session.ManagerBase里边的具体写的操作, 将tomcat的session存储位置指向了Redis:

RedisSessionManager继承了org.apache.catalina.session.ManagerBase并重写了add、findSession、createEmptySession、remove等方法,并将对session的增删改查操作指向了对Redis数据存储的操作。

有兴趣可参考一篇Tomcat中session的管理机制:http://www.cnblogs.com/interdrp/p/4935614.html

不过使用过tomcat-redis-session-manager 的都应该知道,配置相对还是有一点繁琐的,需要人为的去修改Tomcat的配置,需要耦合Tomcat等Servlet容器的代码,并且对于分布式Redis集群的管理并不是很好,与之相对的个人认为比较好的一个框架spring Session可以真正对用户透明的去管理分布式Session。

Spring Session不依赖于Servlet容器,而是Web应用代码层面的实现,直接在已有项目基础上加入spring Session框架来实现Session统一存储在Redis中。如果你的Web应用是基于Spring框架开发的,只需要对现有项目进行少量配置,即可将一个单机版的Web应用改为一个分布式应用,由于不基于Servlet容器,所以可以随意将项目移植到其他容器。

Spring Session使用

官方地址:http://projects.spring.io/spring-session/

官方文档地址:http://docs.spring.io/spring-session/docs/1.3.0.RELEASE/reference/html5/

Spring Session提供了一套创建和管理Servlet HttpSession的方案。Spring Session提供了集群Session(Clustered Sessions)功能,默认采用外置的Redis来存储Session数据,以此来解决Session共享的问题。

一、特性

Spring Session提供以下特性:

  1. API和用于管理用户会话的实现;

  2. HttpSession - 允许以应用程序容器(即Tomcat)中性的方式替换HttpSession;

    1. Clustered Sessions - Spring Session让支持集群会话变得不那么繁琐,并且不和应用程序容器金习性绑定到。

    2. Multiple Browser Sessions - Spring会话支持在单个浏览器实例中管理多个用户的会话。

    3. RESTful APIs - Spring Session允许在headers 中提供会话ID以使用RESTful API。

 

二、基于XML配置方式的Spring Session案例实现

基于SSM框架的一个小案例,Git OS项目代码地址:http://git.oschina.net/xuliugen/spring-session-demo

项目展示:

(1)基本环境需求

进行使用Spring Session的话,首先的是已经安装好的有一个 Redis服务器!

(2)添加项目依赖(最基本的依赖使用)

(3)添加Spring配置文件

添加了必要的依赖之后,我们需要创建相应的Spring配置。Spring配置是要创建一个Servlet过滤器,它用Spring Session支持的HttpSession实现来替换容器本身HttpSession实现。这一步也是Spring Session的核心。

上述代码注释:

LettuceConnectionFactory实例是配置Redis的ConnectionFactory。

注意:

查看源代码可以看到,默认的Redis链接配置为:

因此,如果有自己的Redis配置,请修改,例如下边的配置:

(5)关于Error creating bean with name ‘enableRedisKeyspaceNotificationsInitializer’错误的处理:

添加如下配置让Spring Session不再执行config命令:

如果不添加的话,会报如下错误:

Context initialization failed org.springframework.beans.factory.BeanCreationException: Error creating bean with name'enableRedisKeyspaceNotificationsInitializer' defined in classpath resource [org/springframework/session/data/redis/config/annotation/web/http/RedisHttpSessionConfiguration.class]: Invocation of initmethod failed; nested exception isjava.lang.IllegalStateException: Unable to configure Redis tokeyspace notifications. See http://docs.spring.io/spring-session/docs/current/reference/html5/#api-redisoperationssessionrepository-sessiondestroyedeventCausedby: redis.clients.jedis.exceptions.JedisDataException: ERR unknown command config

(5)在web.xml中添加DelegatingFilterProxy

DelegatingFilterProxy将通过springSessionRepositoryFilter的名称查找Bean并将其转换为过滤器。对于调用DelegatingFilterProxy的每个请求,也将调用springSessionRepositoryFilter。

(6)Spring MVC controller代码用于测试:

(7)测试

访问链接:http://localhost:8080/spring/session/setSession.do?name=xuiliugen&value=123456

使用工具查看Redis内容:

可以发现已经有值了!并且有expirations,可以看到箭头指向的位置,是失效的时间记录值!

(8)到此,Spring Session的使用已经完成!其他具体的细节请参考:http://git.oschina.net/xuliugen/spring-session-demo 项目源代码。

总结

对于分布式环境Session跨域共享的问题,不管是使用开源的框架还是使用自己开发的框架,都需要明白的一个问题是:在Tomcat容器中创建Session是一个很耗费内存的事情。因此,我们在自己写类似框架的时候,我们一定要注意的是,并不是Tomcat为我们创建好了Session之后,我们首先获取Session然后再上传到Redis等进行存储,而是直接有我们自己创建Session,这一点是至关重要的!

注:其实可以使用token+redis就能解决,这边博文只是提供一个思路!

转载于:https://www.cnblogs.com/zrbfree/p/6478329.html

170222、使用Spring Session和Redis解决分布式Session跨域共享问题相关推荐

  1. 使用Spring Session和Redis解决分布式Session跨域共享问题

    大家可以关注一下公众号"Java架构师秘籍" 前言 对于分布式使用Nginx+Tomcat实现负载均衡,最常用的均衡算法有IP_Hash.轮训.根据权重.随机等.不管对于哪一种负载 ...

  2. SpringSession+redis解决分布式session不一致性问题

    七.案例实战:SpringSession+redis解决分布式session不一致性问题 步骤1:加入SpringSession.redis的依赖包 <dependency><gro ...

  3. 8.redis解决分布式session问题 、redis在项目中难点

    a.什么是session session是一种会话技术,我们知道http是无状态协议的,就是这次连接传输数据后,下次连接服务器是不知道这次的请求是谁的,因此我们要做一个标记,让服务器知道每次请求是哪个 ...

  4. 场景应用:利用Redis实现分布式Session

    文章目录 原理:Redis实现分布式Session web开发session 分布式session同步问题 分布式session解决方案 实战:Redis实现分布式Session 技术栈:Spring ...

  5. session传递参数_分布式 Session 之 Spring Session 架构与设计

    作者 | 李增光 杏仁后端工程师.「只有变秃,才能变强!」 ​前言 开始进行 Web 开发时,我们可能会遇到这样的情况,当服务器重启之后,之前的登录状态会失效需要重新登录.又或者你的应用程序部署了不止 ...

  6. Tornado 自定义session,与一致性哈希 ,基于redis 构建分布式 session框架

    Tornado 自定义session,与一致性哈希 ,基于redis 构建分布式 session import tornado.ioloopimport tornado.webfrom myhash ...

  7. 【学习笔记】cookie、session、token和分布式session

    文章目录 cookie和Session session和token cookie和token总结 分布式Session cookie和Session 为什么要有session的出现? 答:是由于网络中 ...

  8. PHP解决http和https跨域,php中http与https跨域共享session的解决方法

    这篇文章主要介绍了http与https跨域共享session的解决方法,需要的朋友可以参考下 遇到了HTTP.HTTPS协议下session共享解决cookie失效的问题,这里提供一个临时解决办法. ...

  9. 解决方案:SpringBoot分布式项目跨域

    解决方案:SpringBoot分布式项目跨域 场景: web端:localhost:8001 后台user服务:localhost:9001 请求:web端请求 后台user服务,报跨域异常 异常信息 ...

最新文章

  1. 异步请求(简单一说)
  2. tidb mysql5.7_MYSQL5.7实时同步数据到TiDB
  3. 设计模式之控制反转和依赖注入的使用小结
  4. 【Linux】一步一步学Linux——hostname命令(73)
  5. 第二弹:超全Python学习资源整理(进阶系列)
  6. magento 上传图片slider Multiple Banner Extension
  7. Spring Boot统一异常处理实践
  8. 还可以这样玩?揭秘打通线上线下新思路
  9. 必须掌握的Java基础知识(一)
  10. myeclipse 创建和访问 servlet 项目
  11. DoIP(四)—— 时间参数
  12. CNVD 与 CNNVD 的区别
  13. Java程序员面试应该准备什么?
  14. 常见视频分辨率及码率
  15. 大数据——海量数据处理的基本方法总结
  16. json数据快速格式化
  17. 学生学籍的计算机管理属于,随着计算机的飞速发展,其应用范围不断扩大,某学校学生学籍的计算机管理属于__应用领域。A.科学计...
  18. 架构思维成长系列教程(十二)- 云平台架构设计
  19. 2020复旦机试题:斗牛
  20. 从永远到永远-Navicat将MySQL数据库复制到另一个Mysql数据库

热门文章

  1. Access to XMLHttpRequest at file from origin ‘null‘ has been blocked by CORS policy谷歌浏览器本地打开项目js文件报错
  2. Ubuntu 16.04 安装 PyInstaller
  3. Go 知识点(07)— 对已经关闭通道进行读写
  4. Git 常用操作(1)- 配置、查看、添加、暂存和提交
  5. Ubuntu 打 deb 包报错(fpm not found、dos2unix not found)
  6. mybatis使用注解开发
  7. Python学习--not语句
  8. LeetCode简单题之移动零
  9. Qt实现 指针式时钟+动态时钟 (详细注释)
  10. 服务器BMC、BIOS、IPMI、UEFI技术解析