加了spring-session-data-redis后,server.servlet.session.timeout失效,因Spring Session接管会话生命周期,实际超时由@EnableRedisHttpSession的maxInactiveIntervalInSeconds控制,默认1800秒。

会话超时配置不生效的常见原因
加了 spring-session-data-redis 依赖后,server.servlet.session.timeout 配置直接失效——这是最常被忽略的第一步。Spring Session 完全接管了会话生命周期,原生 Servlet 容器的 timeout 设置(如 Tomcat 的 session 过期逻辑)被绕过,不再参与 Redis 中 session key 的 TTL 控制。
@EnableRedisHttpSession 的 maxInactiveIntervalInSeconds 参数
真正控制 Redis 中 session 过期时间的是 @EnableRedisHttpSession 注解的 maxInactiveIntervalInSeconds 属性。它决定了 session 在 Redis 中对应的 key 的 TTL(time-to-live),也是客户端无操作后的实际失效时间。
- 必须显式声明一个
@Configuration类并添加该注解,否则使用默认值 1800 秒(30 分钟) - 如果只写
@EnableRedisHttpSession不带参数,就等于maxInactiveIntervalInSeconds = 1800 - 该值不能为 0 或负数;设为 -1 会被 Spring Session 忽略,仍按默认值处理
- 修改后需重启应用才生效,运行时无法热更新
示例:
@Configuration
@EnableRedisHttpSession(maxInactiveIntervalInSeconds = 600) // 10 分钟
public class SessionConfig {
}application.properties 中 spring.session.redis.* 配置项的作用边界
这些配置项对超时时间本身没有直接影响,但容易误以为能替代注解参数:
-
spring.session.redis.flush-mode:只控制 session 数据写入 Redis 的时机(on_save或immediate),不影响 TTL -
spring.session.redis.namespace:仅用于拼接 Redis key 前缀(如spring:session:sessions:{id}),和过期无关 -
spring.session.store-type=redis:只是启用 Redis 存储,不提供任何超时控制能力
换句话说,application.properties 里所有以 spring.session.redis. 开头的配置,都不改 session 的存活时长。
Redis 实际 key 的 TTL 是怎么算出来的
Spring Session 并非简单地把 maxInactiveIntervalInSeconds 当作 SETEX 的秒数——它会在每次 session 访问(读或写)时重置 key 的 TTL。这意味着:
- 用户每刷新一次页面、发一次带 session 的请求,Redis 中对应 key 的过期时间就会被延长
maxInactiveIntervalInSeconds秒 - 这个行为由
RedisOperationsSessionRepository内部的saveDelta和updateExpiration逻辑完成 - 如果你在代码中手动调用
HttpSession.setMaxInactiveInterval(),它会被 Spring Session 忽略(除非你禁用自动配置并自己构造 Repository)
所以,超时不是“创建后固定倒计时”,而是“最后活跃时间 + 固定间隔”——这才是分布式环境下真正可靠的会话续期模型。
最容易被忽略的一点:超时逻辑完全由 Spring Session 自己维护,Redis 服务端不会主动触发 session 失效回调,也不会通知应用。清理靠的是客户端下次访问时发现 key 不存在,或后台定时任务(如 RedisOperationsSessionRepository.Cleaner)扫描过期 key ——后者默认每 30 秒执行一次,且只清理已过期但尚未被访问的 session。这个延迟是设计使然,不是 bug。


















