2019独角兽企业重金招聘Python工程师标准>>>

通常情况下,Tomcat、Jetty等Servlet容器,会默认将Session保存在内存中。如果是单个服务器实例的应用,将Session保存在服务器内存中是一个非常好的方案。但是这种方案有一个缺点,就是不利于扩展。

目前越来越多的应用采用分布式部署,用于实现高可用性和负载均衡等。那么问题来了,如果将同一个应用部署在多个服务器上通过负载均衡对外提供访问,如何实现Session共享?

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

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

Maven依赖

在项目中加入Spring Session的相关依赖包,包括Spring Data Redis、Jedis、Apache Commons Pool:

<!-- Jedis -->
<dependency><groupId>redis.clients</groupId><artifactId>jedis</artifactId><version>2.9.0</version>
</dependency>
<!-- Spring Data Redis -->
<dependency><groupId>org.springframework.data</groupId><artifactId>spring-data-redis</artifactId><version>1.7.3.RELEASE</version>
</dependency>
<!-- Spring Session -->
<dependency><groupId>org.springframework.session</groupId><artifactId>spring-session</artifactId><version>1.2.2.RELEASE</version>
</dependency>
<!-- Apache Commons Pool -->
<dependency><groupId>org.apache.commons</groupId><artifactId>commons-pool2</artifactId><version>2.4.2</version>
</dependency>

配置Filter

在web.xml中加入以下过滤器,注意如果web.xml中有其他过滤器,一般情况下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><dispatcher>REQUEST</dispatcher><dispatcher>ERROR</dispatcher>
</filter-mapping>

Spring配置文件

<bean class="org.springframework.session.data.redis.config.annotation.web.http.RedisHttpSessionConfiguration"/>
<bean class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"><property name="hostName" value="localhost" /><property name="password" value="your-password" /><property name="port" value="6379" /><property name="database" value="10" />
</bean>

只需要以上简单的配置,至此为止即已经完成Web应用Session统一存储在Redis中,可以说是及其简单。

解决Redis云服务Unable to configure Redis to keyspace notifications异常

如果是自建服务器搭建Redis服务,以上已经完成了Spring Session配置,这一节就不用看了。不过很多公司为了稳定性、减少运维成本,会选择使用Redis云服务,例如阿里云数据库Redis版、腾讯云存储Redis等。使用过程中会出现异常:

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

实际上这种异常发生的原因是,很多Redis云服务提供商考虑到安全因素,会禁用掉Redis的config命令:
在错误提示链接的文档中,可以看到Redis需要以下的配置:

redis-cli config set notify-keyspace-events Egx

文档地址:
http://docs.spring.io/spring-session/docs/current/reference/html5/#api-redisoperationssessionrepository-sessiondestroyedevent

首先要想办法给云服务Redis加上这个配置。

部分Redis云服务提供商可以在对应的管理后台配置:
如果不能在后台配置,可以通过工单联系售后工程师帮忙配置,例如阿里云:

完成之后,还需要在Spring配置文件中加上一个配置,让Spring Session不再执行config命令:

However, in a secured Redis enviornment the config command is disabled. This means that Spring Session cannot configure Redis Keyspace events for you. To disable the automatic configuration add ConfigureRedisAction.NO_OP as a bean.

配置:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:util="http://www.springframework.org/schema/util" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd"><bean class="org.springframework.session.data.redis.config.annotation.web.http.RedisHttpSessionConfiguration"/><bean class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"><property name="hostName" value="localhost" /><property name="password" value="your-password" /><property name="port" value="6379" /><property name="database" value="10" /></bean><!-- 让Spring Session不再执行config命令 --><util:constant static-field="org.springframework.session.data.redis.config.ConfigureRedisAction.NO_OP"/></beans>

转载于:https://my.oschina.net/gaoguofan/blog/753955

Spring Session + Redis实现分布式Session共享相关推荐

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

    使用Spring Session和Redis解决分布式Session跨域共享问题 原创 2017-02-27 徐刘根 Java后端技术 前言 对于分布式使用Nginx+Tomcat实现负载均衡,最常用 ...

  2. 基于Spring Session实现JIM分布式Session

    基于Spring Session实现JIM分布式Session 前引 在实际项目中,应用程序经常会以集群方式部署线上,一般来说无状态的应用程序是理想的部署方式,一旦应用程序拥有状态(比如Session ...

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

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

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

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

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

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

  6. php session redis db,php session redis 配置

    具体环境: 一台apache+php的服务器(yum安装remi源及配置 httpd-2.2.15 php-5.4.45) 一台redis服务器(yum安装remi源及配置 redis-3.2.6) ...

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

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

  8. springboot+redis实现分布式session共享

    官方文档,它是spring session项目的redis相关的一个子文档:https://docs.spring.io/spring-session/docs/2.0.0.BUILD-SNAPSHO ...

  9. 如何利用Redis实现分布式Session?

    在web开发中,我们会把用户的登录信息存储在「session」里.而session是依赖于「cookie」的,即服务器创建session时会给它分配一个唯一的ID,并且在响应时创建一个cookie用于 ...

最新文章

  1. 寻找人机之间的中间地带-评述3本人机协作的书
  2. python语言自学-为什么建议大家都学习Python语言?原因在这
  3. latch.await java有什么作用_java相关:CountDownLatch源码解析之await()
  4. 内置对象和内置函数_内置假对象
  5. 计算机网络 --- 数据链路层aloha协议
  6. google ads 黑名单目录
  7. pixhawk学习笔记-----mavlink
  8. 有哪些皮一下就很开心的句子?
  9. redis 多进程_Redis 持久化
  10. 为啥用计算机分析模拟,模拟电路的计算机分析与设计——Pspice程序应用
  11. spss相关分析(spss统计分析实验教程,谢蕾蕾)
  12. Python深度学习笔记(三)二分类模型
  13. 算法之美 - 电子书下载(高清版PDF格式+EPUB格式)
  14. Echart甘特图实现效果 + 配带抽成方法 + 源码
  15. 企鹅撞冰块Java游戏_亲子桌面游戏玩具 拯救企鹅敲打冰块玩法
  16. 能否将一个网址(如QQ空间网址),打包成APK,然后别人下载APK安装到手机后,点击进入这个网址?
  17. 针对唯一化实例对话框程序,及其命令行操作方法
  18. 随机梯度下降法概述与实例
  19. 【FPGA】Verilog实现奇偶分频
  20. 分布式系统设计模式 - 最低水位线(Low-Water Mark)

热门文章

  1. UITableview高度计算
  2. zabbix中文配置指南
  3. vue1和vue2获取dom元素的方法 及 nextTick() 、$nextTick()
  4. 了解DJango模板系统
  5. 关于node.js杂记
  6. 角色和权限Hibernate实体映射配置
  7. 解决 QtCreator 3.5(4.0)无法输入中文的问题
  8. Python基础学习:svn导出差异文件脚本
  9. 参考TinyOS官方网站实现BlinkToRadio
  10. Became Jane(成为简.奥斯丁)