Spring Session + Redis 是目前最稳妥、侵入性最小的分布式会话方案,只需添加依赖、配置 @EnableRedisHttpSession 注解并连接 Redis 即可生效;若遗漏该注解或 Redis 不可达,会自动退化为默认内存 Session,导致多实例下登录状态丢失。

直接说结论:Spring Session + Redis 是目前最稳妥、侵入性最小的方案,不用改业务代码,只要加依赖、配注解、连上 Redis 就能跑通。但如果你漏了 @EnableRedisHttpSession 或 Redis 连接不通,会话照样“飘”——不是没生效,而是退化回了默认内存 Session。
为什么 HttpSession 在多实例下会“丢”
根本原因不是 Spring Boot 有问题,而是 Servlet 规范里 HttpSession 默认绑定在单个 JVM 内存中。用户登录后生成的 JSESSIONID Cookie 被浏览器带上,但 A 节点存的 session 数据,B 节点根本看不到。
常见错误现象包括:
- 登录后刷新页面跳回登录页
- 同一用户在不同浏览器标签页行为不一致(一个已登录,一个提示未登录)
- Nginx 日志显示请求被轮询到不同 upstream,但用户状态断开
这不是负载均衡的问题,也不是前端 Cookie 没传,而是服务端压根没去 Redis 查——因为没启用 Spring Session。
@EnableRedisHttpSession 必须加在启动类上
这个注解是开关,不加就等于没装插头。它会自动注册 RedisOperationsSessionRepository,替换掉容器原生的 HttpSession 实现。
实操建议:
- 必须加在
@SpringBootApplication标记的主类上,不能放在配置类或 Controller 里 - 推荐显式指定过期时间:
@EnableRedisHttpSession(maxInactiveIntervalInSeconds = 1800),避免依赖 Redis 默认 TTL - 如果项目用了 Spring Security,这个注解要放在
@EnableWebSecurity同一个类里,否则 Security 的认证上下文可能不同步 - Spring Boot 3.x 中该注解仍在
org.springframework.session.config.annotation.web.http包下,别导错包
Redis 序列化策略容易导致反序列化失败
Spring Session 默认用 JdkSerializationRedisSerializer,但一旦你往 session.setAttribute() 里塞了没实现 Serializable 的对象(比如 Lombok 的 @Data 类没加 implements Serializable),Redis 里存的是乱码字节,读取时直接抛 ClassNotFoundException 或静默失败。
创建全面的交接文档,使新AI代理能够无缝继续工作,消除歧义。解决上下文耗尽问题。 时机:(1)用户请求保存交接,(2)上下文即将满,(3)主要任务完成,(4)会话结束,(5)恢复工作时。 关键词:保存状态、创建交接、上下文已满、暂停、从...恢复、加载交接、保存进度、会话转移、交接
解决方法:
- 要么统一让所有存入 Session 的对象实现
Serializable并加private static final long serialVersionUID = 1L; - 要么自定义序列化器,例如换成
GenericJackson2JsonRedisSerializer,更兼容、可读性强、跨语言友好 - 注意:更换序列化器后,Redis 里旧的 JDK 序列化数据无法自动兼容,上线前需清空
spring:session:sessions:相关 key
Cookie 的 domain 和 path 配置影响跨实例识别
即使 Redis 存对了、注解也加了,如果 Nginx 反向代理后域名或路径变了,浏览器可能不会把 JSESSIONID Cookie 发给后端。
典型场景:
- 前端访问
https://app.example.com,Nginx 转发到http://127.0.0.1:8080,但 Cookie 的domain被设成app.example.com,而本地服务没配 domain,导致 Cookie 不携带 - 多个子系统共用一套登录,但各自 path 不同(如
/admin和/user),cookie.path设太窄会互相看不到
建议在 application.yml 中显式配置:
spring:
session:
cookie:
domain: example.com
path: /
http-only: true
secure: true
其中 domain 必须带点开头(如 .example.com),才能被子域共享;secure: true 表示只走 HTTPS 传输 Cookie,生产环境务必开启。
最容易被忽略的一点:Spring Session 不会自动同步 HttpSessionListener 的事件(比如 sessionCreated)。如果你在监听器里写了日志、埋点或清理逻辑,它们在 Redis 模式下不会触发——因为 session 生命周期管理已交由 Redis 和 Spring Session 自己维护。

















