通常情况下,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
首先要想办法给云服务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>
相关推荐
Spring Session的核心思想是将session数据从传统的JVM内存中移出,存储到一个独立的数据存储系统,如Redis,这样可以实现session在多台服务器之间的共享。 Redis是一个高性能的键值数据库,常用于缓存和消息代理。...
本项目“Springboot+SpringSecurity+SpringSession+Redis+Mybatis-Plus+Swwager”整合了Spring Boot、Spring Security、Spring Session、Redis、Mybatis-Plus以及Swagger等技术,旨在构建一个强大的、安全的、具有...
本文档旨在介绍如何使用 Spring Boot、Shiro 和 Redis 实现分布式 session 共享,以解决 Web 应用程序的登录 session 统一问题。 2. 相关依赖 在实现 session 共享之前,需要在项目中引入相关依赖项,包括: * ...
SpringSession结合Redis实现Session共享是Web开发中一种常见的解决方案,特别是在分布式系统中,为了保持用户在不同服务器之间访问时的会话一致性。本案例旨在教你如何配置和使用SpringSession与Redis来达到这一目的...
标题 "nginx+spring-session+redis 实现session共享" 涉及到的是在分布式系统中如何处理会话(session)共享的问题。在分布式环境中,由于用户请求可能被路由到不同的服务器节点,传统的session存储方式(如JVM内存...
标题 "Spring Boot + Spring Session + Redis" 涉及到的是在Java开发中,使用Spring Boot框架集成Spring Session和Redis来实现会话管理的技术方案。这个解决方案主要解决分布式系统中的session共享问题,使得用户在...
通过这种方式,你可以实现基于SpringSession和Redis的Session共享,从而在分布式系统中保持用户状态的一致性。这种解决方案不仅适用于微服务架构,也可以用于任何需要跨服务器共享Session的场景。同时,由于Session...
SSM+Redis 实现Session共享是现代Web应用中常见的技术组合,主要目的是在分布式系统中保持用户Session的一致性。SSM是指Spring、Spring MVC和MyBatis这三大Java Web开发框架的组合,而Redis则是一种高性能的键值存储...
### Spring-Session与Redis结合实现Session共享 在分布式系统中,单点登录(Single Sign-On,...综上所述,通过Spring-Session结合Redis的方式,可以轻松地实现Session共享,为分布式环境下的应用提供了极大的便利。
总之,这个压缩包提供的"spring-session+spring+redis"组合,是Java Web开发中实现高可用分布式会话管理的一种常见解决方案。通过使用Redis作为存储,结合Spring Session的便捷性和Jedis的高效访问,可以在复杂环境...
Spring Session通过将session数据持久化到Redis中,使得多台服务器可以共享同一份session数据,从而实现了分布式环境下的会话保持。 **Spring Session的核心概念与工作原理** 1. **SessionRepository**: Spring ...
为了解决这个问题,Spring Session提供了一种优雅的解决方案,特别是结合Redis作为持久化存储时,可以实现高效的分布式Session管理。本文将详细介绍Spring Session与Redis集成,以及如何自定义Session来应对分布式...
6. **Session共享实现步骤**: - 配置Redis:首先,需要安装并配置Redis服务,确保其能够正常运行。 - 集成Spring Session:Spring Session库提供了一种将session存储在外部存储(如Redis)中的方法。需要在Spring...
标题中的“Spring-session2整合spring5+redis”指的是在Spring框架的第五个主要版本(Spring 5)中,集成Spring Session 2与Redis数据库来管理Web应用的会话(Session)。Spring Session是一个开源项目,旨在提供一...
在本项目中,Spring Session 配合Redis 实现了session的分布式存储,解决了多台服务器下的session同步问题,确保用户会话的一致性。 通过以上组件的集成,项目能够实现高效的数据库操作、灵活的Web服务构建、快速的...
在IT行业中,构建高效、可扩展的Web服务是至关重要的,而"nginx+redis实现session共享"的主题就涉及到了这一核心需求。为了实现单点登录(Single Sign-On, SSO)以及跨应用的session共享,我们可以结合使用Nginx作为...
本文将详细介绍如何使用Spring、Redis和Nginx来实现Tomcat集群中的Session共享,以及提供相关的源码下载。 首先,我们来看Spring框架。Spring是Java开发中最流行的开源框架之一,它提供了丰富的功能和模块,包括...
这个"spring+redis整合"项目展示了如何利用Spring框架和Redis数据库来实现一个高效的、高可用的登录系统,其中会话(Session)由Redis进行管理,同时支持通过Nginx进行负载均衡。以下是关于这一主题的详细知识讲解。...
具体实现过程中,通常会在后端应用中集成一个session存储器,如Java的Spring Session库,它可以方便地将session操作委托给Redis。同时,Nginx配置中需要设置一个upstream块,定义后端服务器的地址,并启用proxy_pass...