tomcat 无“会话超时环境变量”,session 超时必须通过 web.xml 的 (分钟)、context.xml 的 maxinactiveinterval(秒)或代码中 setmaxinactiveinterval()(秒)设置,环境变量如 catalina_opts 无效。

Tomcat 没有“会话超时环境变量”这个概念——你无法通过 JAVA_OPTS、CATALINA_OPTS 或系统级环境变量直接控制 session 过期时间。所有有效的 session 超时设置都必须落在 Tomcat 的配置文件或应用代码中,环境变量对 HttpSession 生命周期无影响。
为什么 CATALINA_OPTS 不能设 session 超时
环境变量(如 CATALINA_OPTS)只影响 JVM 启动参数(堆大小、GC 策略、系统属性等),而 session 超时是 Web 容器层的逻辑配置,由 StandardManager 实例在运行时读取并生效。即使你用 -Dsession.timeout=1800 设置了系统属性,Tomcat 默认不会读取它来覆盖 session 行为。
常见误操作包括:
- 在
setenv.sh中写CATALINA_OPTS="$CATALINA_OPTS -Dsession.maxInactiveInterval=1800"—— 无效,StandardManager不认这个 key - 试图用
export SESSION_TIMEOUT=30然后期望 web.xml 自动读取 —— XML 解析器不支持环境变量插值 - 混淆请求超时(
connectionTimeout在server.xml的Connector里)和 session 超时 —— 完全不同机制
web.xml 中的 <session-timeout></session-timeout> 是最常用且推荐的方式
该配置作用于整个 Web 应用,单位是分钟,会被容器自动转换为秒传给 Manager。优先级高于 Tomcat 全局默认值($CATALINA_HOME/conf/web.xml 中的 30 分钟),但低于代码中调用 setMaxInactiveInterval()。
示例(放在你项目的 WEB-INF/web.xml 中):
<session-config><session-timeout>45</session-timeout></session-config>
注意:
- 值为
0或负数(如-1)表示 session 永不过期(不建议生产环境使用) - 修改后需重启应用(或重新部署 WAR),热加载不触发 session 配置重载
- 若项目用了 Spring Boot 内嵌 Tomcat,此配置仍有效;但更推荐用
server.servlet.session.timeout=45m(application.properties)
context.xml 或 server.xml 中配 maxInactiveInterval 的实际效果
这是真正作用于 Manager 实例的底层参数,单位是秒,优先级高于 web.xml,但仅对指定 Context 生效。常用于多租户或同一 Tomcat 部署多个应用且需差异化 session 管理的场景。
例如,在 $CATALINA_HOME/conf/context.xml(全局)或 META-INF/context.xml(应用级)中写:
<context><manager classname="org.apache.catalina.session.StandardManager" maxinactiveinterval="2700"></manager></context>
关键点:
-
maxInactiveInterval是 Manager 的构造参数,不是 Context 的属性(所以defaultSessionTimeOut在server.xml的<context></context>标签里已被废弃,Tomcat 9+ 不再识别) - 如果同时在
context.xml和web.xml中设置了超时,前者优先生效 - 改完
context.xml必须重启 Tomcat,因为 Manager 在容器启动时初始化,不可动态替换
代码中调用 session.setMaxInactiveInterval() 的边界条件
这是唯一能对单个 session 实例做差异化控制的方式,比如登录后根据用户角色延长 timeout,或 API 请求临时缩短。
典型用法:
HttpSession session = request.getSession(); session.setMaxInactiveInterval(600); // 单位:秒
但要注意:
- 必须在 session 创建后、响应提交前调用,否则抛
IllegalStateException - 该设置只影响当前 session 实例,不影响其他 session,也不改变应用级默认值
- 若前端用了 AJAX 心跳保活(如每 5 分钟发一次空请求),
setMaxInactiveInterval()的实际效果会被掩盖——因为每次请求都会刷新 lastAccessedTime - 在 Filter 中设置时,确保不是在
response.isCommitted() == true之后执行
真正容易被忽略的是:session 超时判断依赖服务器端时间戳,和客户端时钟、浏览器休眠、网络延迟都无关;但如果你的应用做了 session 复制(如集群环境),要确认所有节点的系统时间同步(NTP),否则会出现部分节点提前失效的情况。











