Spring Session + Redis实现Session共享

article/2025/9/17 9:21:42

功能需求
通常情况下,Tomcat的Servlet容器会默认将Session保存在内存中。如果是单个服务器实例的应用,将Session保存在服务器内存中是一个常用的选择,但是随着服务器数量的增多,这种方法变得不容易扩展。
在这里插入图片描述

比如上图中,User1通过负载均衡登录到Server1中,并把Session保存在了Server1中,但是此时User1进行操作2的时候访问到了Server2,但是Server2上面并没有保存User1的session,就会产生重新登录的问题。

目前越来越多的应用采用分布式部署,用于实现高可用性和负载均衡等。那么问题来了,如果将同一个应用部署在多个服务器上通过负载均衡对外提供访问,如何实现Session共享?
实现Session共享的方案很多,其中一种常用的就是使用Tomcat等服务器提供的Session共享功能,将Session的内容统一存储在一个数据库(如MySQL)或缓存(如Redis)中。

这里介绍另一种实现Session共享的方案,不依赖于Servlet容器,而是Web应用代码层面的实现,直接在已有项目基础上加入Spring Session框架来实现Session统一存储在Redis中。


正如上图中,我们通过Spring Session将User1进行操作1时产生的Session保存在了Redis中,这样用户在访问Server2的时候就可以从Redis中读取User1 Session并验证,做到了多集群中的Session共享。

如果你的Web应用是基于Spring框架开发的,只需要对现有项目进行少量配置,即可将一个单机版的Web应用改为一个分布式应用,由于不基于Servlet容器,所以可以随意将项目移植到其他容器。

准备工作
安装部署Redis, 可参考链接
使用方法
pom.xml中引入Redis相关的依赖(其他自行配置)

 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency><dependency><groupId>org.springframework.session</groupId><artifactId>spring-session-data-redis</artifactId></dependency><dependency><groupId>redis.clients</groupId><artifactId>jedis</artifactId></dependency>

Configure设置
application.properties

#Redis
spring.redis.host=127.0.0.1
## Redis服务器连接端口
spring.redis.port=6379
## 连接超时时间(毫秒)
spring.redis.timeout=300ms
## Redis服务器连接密码(默认为空)
spring.redis.password=135246
## 连接池中的最大连接数
spring.redis.jedis.pool.max-idle=10
## 连接池中的最大空闲连接
spring.redis.lettuce.pool.max-idle=8
## 连接池中的最大阻塞等待时间
spring.redis.jedis.pool.max-wait=-1ms
## 连接池最大阻塞等待时间(使用负值表示没有限制)
spring.redis.lettuce.shutdown-timeout=100ms
spring.session.store-type=redis
server.servlet.session.timeout=2000s
spring.session.redis.flush-mode=on_save
spring.session.redis.namespace=spring:session

设置Redis配置(这一步仅用于配置缓存,跟Spring Session没有关系,可以不配置)

@Configuration
@EnableCaching
@PropertySource(value = "classpath:/application.properties")
public class RedisConfig extends CachingConfigurerSupport {@Value("${spring.redis.host}")private String redisHost;@Value("${spring.redis.port}")private int redisPort;@Value("${spring.redis.password}")private String redisPassword;/*** 配置连接工厂* @return*/@Bean(name = "factory")public RedisConnectionFactory redisConnectionFactory() {RedisStandaloneConfiguration redisStandaloneConfiguration = new RedisStandaloneConfiguration(redisHost, redisPort);redisStandaloneConfiguration.setPassword(RedisPassword.of(redisPassword));return new JedisConnectionFactory(redisStandaloneConfiguration);}/*** 配置缓存管理器* @param factory 连接工厂* @return*/@Beanpublic CacheManager cacheManager(RedisConnectionFactory factory) {return new RedisCacheManager(RedisCacheWriter.nonLockingRedisCacheWriter(factory),RedisCacheConfiguration.defaultCacheConfig().entryTtl(Duration.ofMinutes(30)).disableCachingNullValues());}/*** Redis操作模板* @param factory 连接工厂* @return*/@Beanpublic RedisTemplate<String, String> redisTemplate(RedisConnectionFactory factory) {StringRedisTemplate template = new StringRedisTemplate(factory);Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class);ObjectMapper om = new ObjectMapper();om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);jackson2JsonRedisSerializer.setObjectMapper(om);template.setKeySerializer(jackson2JsonRedisSerializer);template.setValueSerializer(jackson2JsonRedisSerializer);template.afterPropertiesSet();return template;}
}

使用spring-session-data-redis实现session共享,pom中引入该依赖(上文已添加),添加SessionConfig配置类。

@Configuration
@EnableRedisHttpSession
public class SessionConfiguration {}

编写一个Controller并进行测试

@RequestMapping("testSessionTimeOut")
public String testSessionTimeOut(Long id, HttpSession session, Model model){User user = userService.getUserById(id);System.out.println("sessionId-------->"+session.getId());model.addAttribute("user", JSON.toJSONString(user));session.setAttribute("user",JSON.toJSONString(user));return "hello world";
}

最终效果
浏览器中输入http://localhost/session/testSessionTimeOut(可在多台机器上部署测试,这里只测试Session是否保存在了Redis中)

控制台输出结果



http://chatgpt.dhexx.cn/article/TT9VccZT.shtml

相关文章

nginx实现session共享

在nginx实现了负载均衡之后&#xff0c;用户第一次请求的tomcat和第二次请求的tomcat基本不是同一个&#xff0c;但是你在第一次请求放在session中的值只有一个tomcat1才有&#xff0c;第二个请求的那个tomcat2里面是没有的。这样就出现了用户不停登入的情况。为了解决这个sess…

tomcat配置session共享

tomcat官网 打开 tomcat 官网&#xff1a; http://tomcat.apache.org/ &#xff0c; 找到需要配置的tomcat版本的文档&#xff0c;这里以 tomcat7 为例&#xff0c; 找到对应的 Clustering 配置&#xff08;因为配置session共享&#xff0c;就是配置集群&#xff09;&#xff…

Nginx——Session共享

文章目录 其他文章1、Session共享1.1、session 一致性解决方案1.1.1、session 复制1.1.2、共享 session 1.2、安装memcached1.2.1、 node2 和 node3 上安装 jdk 和 tomcat1.2.2、nginx1 上安装 memcached 其他文章 Nginx——安装Nginx1.6.1 Nginx——工作模型 Nginx——配置文…

Springboot整合springsession实现session共享

Springboot整合springsession实现session共享 简介 session我们之前有介绍过&#xff08;可见springboot整合springsecurity&#xff09;&#xff0c;简单来说就是将用户信息或者数据存储在服务器上&#xff0c;通常用于验证用户身份或者避免通过获取相关信息。 但是&#x…

集群产生的session共享问题

前言&#xff1a; 为了解决集群产生的session共享问题&#xff0c;我们首先需要知道以下三个概念&#xff1a; cookiesessionnginx ​ 下面将逐个分析。 Cookie 1.Cookie是什么 ​cookie的中文翻译是曲奇&#xff0c;小甜饼的意思。cookie其实就是一些数据信息&#xff0c…

Websocket Session 共享解决

Websocket Session 共享解决&#xff08;方案一&#xff09; 既然Websocket Session 不能直接序列化然后存储&#xff0c;而且如果用户请求的时候&#xff0c;开始与集群中的A 节点创建链接&#xff0c;就算把这个 Session 拿到B 节点去再给用户Push 消息&#xff0c;应该也…

使用redis实现session共享

继上一遍文章&#xff0c;使用nginx实现负载均衡以后&#xff0c;新的问题又产生了&#xff0c;当使用负载均衡以后&#xff0c;我们如何实现session共享&#xff0c;因为session是保存在服务端的&#xff0c;对于单体应用来说这不是问题&#xff0c;因为只有一个服务器&#x…

Session共享问题-session原理

问题1&#xff1a;微服务情况下。域名不同。session不共享 问题2&#xff1a;分布式系统下。同一个域名下&#xff0c;多个服务。session会出现不同步问题&#xff08;例如第一次访问的是A服务&#xff0c;保存了。第二次访问了B,查询到的还是没信息&#xff09; 解决&#xf…

Springboot:Session共享

1、概述 传统单机web应用中&#xff0c;一般使用tomcat/jetty等web容器时&#xff0c;用户的session都是由容器管理。浏览器使用cookie中记录sessionId&#xff0c;容器根据sessionId判断用户是否存在会话session。这里的限制是&#xff0c;session存储在web容器中&#xff0c…

Java -- SpringSession实现session共享

在集群系统中&#xff0c;经常需要将 Session 进行共享。不然会出问题&#xff1a;用户在系统A上登陆以后&#xff0c;假如后续的一些操作被负载均衡到系统B上面&#xff0c;系统B发现本机上没有这个用户的 Session &#xff0c;会强制让用户重新登陆。 如在同域名&#xff0c…

shiro分布式session共享

当我们开发的程序需要跑在多个tomcat容器或者多台机器上时&#xff0c;shiro的默认session存储就不能满足我们的需求了&#xff0c;其中shiro默认的session是存储在运行jvm内存中的&#xff0c;使用的AbstractSessionDAO抽象类的一个子类MemorySessionDAO&#xff0c;当我们需要…

tomcat+redis实现session共享

注意&#xff1a;在实际应用中&#xff0c;发现该方案会不定期导致Tomcat假死&#xff08;怀疑Redis连接未释放&#xff09;&#xff0c;慎用。 服务器192.168.14.132和192.168.14.133&#xff0c; 均已经安装tomcat&#xff0c;tomcat安装过程不再赘述。 采用192.168.14.132…

Session共享问题

Session共享及Session保持或者叫做Session⼀致性 1、Session问题原因分析 出现这个问题的原因&#xff0c;从根本上来说是因为Http协议是无状态的协议。客户端和服务端在某次会话中产生的数据不会被保留下来&#xff0c;所以第⼆次请求服务端无法认识到你曾经来过&#xff0c;…

session共享(redis实现)

引言 大厂很多项目都是部署到多台服务器上&#xff0c;这些服务器在各个地区都存在&#xff0c;当我们访问服务时虽然执行的是同一个服务&#xff0c;但是可能是不同服务器运行的&#xff1b; 在我学习项目时遇到这样一个登录情景&#xff0c;假设有如下三台服务器&#xff0…

如何实现session共享的几种解决方案?

先了解一下为什么会出现这种session共享的解决方案&#xff1f; 随着互联网公司的项目在微服务和分布式的环境下进行的搭建&#xff0c;导致一个项目可能分别部署在几个甚至很多的服务器集群下&#xff0c;此时就会出现一个问题当用户进行一个session会话的时候&#xff0c;比…

session共享几种方式

Session共享三种方式 1.nginx基于ip_hash负载均衡。 只需要更改nginx.conf配置文件。添加ip_hash就可以了。 缺点&#xff1a;1.由于ip_hash分配tomcat的时候用的是除法&#xff0c;所以新添加一台服务器会导致分配不到原来程序上&#xff0c;session会丢失。2.同一个公网ip…

session共享学习

一、Session共享 1 什么是Session共享    是指在一个浏览器对应多个Web服务时&#xff0c;服务端的Session数据需要共享。 2 Session共享应用场景 单点登录Web服务器集群等 3 Session共享常见的解决方案 3.1 Session复制       通过对应用服务器的配置开启服务器的Sess…

redis实现session共享

session共享 什么是session&#xff1f; 由于 HTTP 协议是无状态的协议&#xff0c;所以服务端需要记录用户的状态时&#xff0c;就需要用某种机制来识具体的用户。Session 是另一种记录客户状态的机制&#xff0c;不同的是 Cookie 保存在客户端浏览器中&#xff0c;而 Sessi…

UART协议概述与实现

UART协议概述&#xff08;一&#xff09; 协议描述关键代码逻辑写在最后 协议描述 常见的三大低速通信协议之一&#xff0c;UART&#xff0c;通用异步收发协议。非常简单的协议&#xff0c;协议细节不需要多说&#xff0c;只说需要注意的点。空闲位为高位&#xff0c;起始位为…

UART协议简述及编程

UART原理简述 通用异步收发器简称UART&#xff08;universal asynchronous receiver transmitter&#xff09;。他的用途很广泛&#xff0c;一般常用的就是用来输出打印的信息&#xff0c;也可以外接各种模块&#xff0c;例如GPS和蓝牙等。 正是因为这种协议非常的简单可靠&…