千家信息网

pringboot集群之如何看待session和redis

发表于:2026-11-04 作者:千家信息网编辑
千家信息网最后更新 2026年11月04日,这篇文章将为大家详细讲解有关pringboot集群之如何看待session和redis,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。在谈到集群方案的时
千家信息网最后更新 2026年11月04日pringboot集群之如何看待session和redis

这篇文章将为大家详细讲解有关pringboot集群之如何看待session和redis,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。

在谈到集群方案的时候,第一个会遇到的问题就是session问题,在单机上,session的问题从来都是web容器解决的,我们主要是用,但是集群意味着多容器。如果负载均衡是随机分配服务器访问的话,很容易造成在A服务器登录后,下次访问是走的是B服务器,结果B服务器的web容器里面并没有该用户的session,结果就悲剧了。那么怎么办呢,当然是redis来处理,redis把session集中存储起来,不管哪台服务器存取session都是走redis,本地服务器不保存session,这个问题就完美的解决了。这个方案落到具体的实现上,首先我想到的就是spring自己的解决方案,spring session。

1、spring session+redis跑起来

spring session+redis的方案非常的简单,大家请按步骤来:

步骤1:pom文件加starter

                                org.springframework.boot                        spring-boot-starter-data-redis                                                org.springframework.boot                        spring-boot-starter-web                                                        org.springframework.session                        spring-session-data-redis                

spring-boot-starter-web是引入web依赖,spring-boot-starter-data-redis是redis的存取,spring-session-data-redis就是把redis作为session的存储位置并做相关操作的依赖。

步骤2:把redis的配置写到application.properties里面去

# REDIS# Redis数据库索引(默认为0)spring.redis.database=0  # Redis服务器地址spring.redis.host=myip# Redis服务器连接端口spring.redis.port=6379  # Redis服务器连接密码(默认为空)spring.redis.password=password# 连接池最大连接数(使用负值表示没有限制) 默认 8spring.redis.lettuce.pool.max-active=8# 连接池最大阻塞等待时间(使用负值表示没有限制) 默认 -1spring.redis.lettuce.pool.max-wait=-1# 连接池中的最大空闲连接 默认 8spring.redis.lettuce.pool.max-idle=8# 连接池中的最小空闲连接 默认 0spring.redis.lettuce.pool.min-idle=0

步骤3:把相关注解加到启动类里面去

@SpringBootApplication@EnableCaching@EnableRedisHttpSession(maxInactiveIntervalInSeconds = 86400*30)public class RedisApplication {        public static void main(String[] args) {                SpringApplication.run(RedisApplication.class, args);        }}

其中@EnableCaching表示开启缓存,因为我们在application.proerties文件里面配置了redis,所以默认redis就作为项目的缓存;@EnableRedisHttpSession表示redis存储httpsession,后面session就会自动存储到redis里面了。

我们开一个controller,试一下是不是这样:

@RestControllerpublic class IndexController {      @RequestMapping("/saveSession")    String saveSession(HttpSession session) {        session.setAttribute("mySession", "lalala");        return session.getId();    }        @RequestMapping("/getSession")    String getSession(HttpSession session) {        String mySessionString = session.getAttribute("mySession").toString();        return mySessionString;    }

saveSession和getSession的方法很简单,一个存session,一个取session

我们用redis-cli查看下这个session是否存到了redis:

可见,session自动就存储到了redis。可见,实现session到redis,然后共享,非常的简单。

这一块的源码可以看这里

2、session在redis的存储结构

上面用redis-cli查看session的时候,可以看到的确session存进去了,但这个存储的方式却不是那么明了,可以拿来说道说道。

2.1、namespace和其他属性

首先是存储的key值,比如上面截图中的,是这么一段:

spring:session:sessions:54abb3f7-909a-46c8-ab4c-1b515eff69b1

其中spring:session是spring session在redis里面的命名空间,默认就是"spring:session",在org.springframework.session.data.redis.config.annotation.web.http.RedisHttpSessionConfiguration的源代码里面可以看到:

这个namespace是可以改的,在@EnableRedisHttpSession的源代码里面我们可以看到,有这么几个参数是可以传进去配置的

public @interface EnableRedisHttpSession {        /**         * The session timeout in seconds. By default, it is set to 1800 seconds (30 minutes).         * This should be a non-negative integer.         * @return the seconds a session can be inactive before expiring         */        int maxInactiveIntervalInSeconds() default MapSession.DEFAULT_MAX_INACTIVE_INTERVAL_SECONDS;        /**         * Defines a unique namespace for keys. The value is used to isolate sessions by         * changing the prefix from default {@code spring:session:} to         * {@code :}.         * 

* For example, if you had an application named "Application A" that needed to keep * the sessions isolated from "Application B" you could set two different values for * the applications and they could function within the same Redis instance. * @return the unique namespace for keys */ String redisNamespace() default RedisOperationsSessionRepository.DEFAULT_NAMESPACE; /** * Flush mode for the Redis sessions. The default is {@code ON_SAVE} which only * updates the backing Redis when {@link SessionRepository#save(Session)} is invoked. * In a web environment this happens just before the HTTP response is committed. *

* Setting the value to {@code IMMEDIATE} will ensure that the any updates to the * Session are immediately written to the Redis instance. * @return the {@link RedisFlushMode} to use * @since 1.1 */ RedisFlushMode redisFlushMode() default RedisFlushMode.ON_SAVE; /** * The cron expression for expired session cleanup job. By default runs every minute. * @return the session cleanup cron expression * @since 2.0.0 */ String cleanupCron() default RedisHttpSessionConfiguration.DEFAULT_CLEANUP_CRON;}

  • maxInactiveIntervalInSeconds是session中的数据的过期时间(不是session在redis中的过期时间)

  • redisNamespace就是session在spring session在redis里面key的命名空间

  • redisFlushMode是redis保存session的方式,默认 ON_SAVE。有两种方式:?IMMEDIATE:一旦创建session的时候就立即保存;ON_SAVE:创建session的时候不会保存,但当往session中添加数据的时候就会保存

  • cleanupCron session过期时的数据清扫定时任务,默认的配置时1分钟1次,为什么要配置这个,后面会讲。

我们在@EnableRedisHttpSession配置一个namespace看下效果

@EnableRedisHttpSession(maxInactiveIntervalInSeconds = 86400*30,redisNamespace = "wphmoon:session")public class RedisApplication {......}

访问上面的saveSession方法,看下session在redis里面的数据结构:

2.2 session在redis里面的存储结构

上图可以看到命名空间已经修改了。我们再来看下key后面的value是什么样的

失败了,原因是session存到redis并不是用字符串类型来存,它存储的格式是

用的是hash,我们用hget来看一下

查不到,原因是mySession并不是完整的field name,完整的是这样的

看到熟悉的lalala就知道这次终于查到了,完整的fieldName要在我们命名的Attribute前面加上sessionAttr。但是在lalala前面的"\xac\xed\x00\x05t\x00\x06"又是什么鬼?

这个就要靠翻源代码了,于是我开始到spring-session-data-redis-XXX.jar里面去找,看到了SpringSessionRedisOperations这个类,这个名字一看就象是把session推到redis的操作类(它本身是个注解,代码里面作者很贴心的告诉我们具体实现去看哪些)。

在RedisOperationsSessionRepository类里面,我意外的发现了这个

原来sessionAttr:是在这里定义的,我还发现了这个

原来namespace要加上sessions是在这里,但我们这次翻代码的主要原因,查看value内容里面的乱字符串却不在这里,在另外一个类ReactiveRedisOperationsSessionRepository里面。它实际操作session存储的方法是调用另外一个接口类:

这个接口的实现类最终只有两个,还是继承关系。

看到RedisTemplate总算看到了老朋友,我们使用redis的时候最常用到的工具。看下它操作hash的方法

从参数的名字就能看出来,这个肯定经过了序列化(serialization)处理,所以进到RedisSerializationContext里面可以看到这一句

看来,所有session存入redis里面的时候,需要做序列化的处理,而真正字符串前面的那一堆,就是序列化的标记内容。

关于pringboot集群之如何看待session和redis就分享到这里了,希望以上内容可以对大家有一定的帮助,可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看到。

存储 服务器 服务 时候 就是 配置 数据 集群 内容 方案 方法 步骤 问题 最大 原因 字符 字符串 容器 序列 方式 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 广东猪兼强互联网科技有限公司 中国互联网科技发展 贷财互联网科技 宜安科技 互联网金融 华中科技大学互联网 汇久创客互联网科技 科技互联网公司logo 互联网科技博客 互联网金融监管科技 中正互联网科技招聘 玖二柒互联网科技公司待遇 深圳前海聚择互联网科技有限公司 互联网为啥属于高科技 中国互联网十大科技股排名 四川慕妮娅互联网科技有限公司 特约风豹互联网科技为什么扣费 互联网科技实习生岗位 广东鹅鹅鹅互联网科技有限公司 山东蛋芒互联网科技有限公司 宁波允成互联网科技有限公司 互联网科技工作委员会主任 金融科技创新监管互联网金融 碳银互联网科技 贷财互联网科技 电子科技大学互联网 互联网养老 桔豆科技 互联网科技公司有风险吗 科技类公司包括互联网吗 互联网科技大赛获奖感言 广州百诚互联网科技有限公司官网
0