You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Ubuntu环境Tomcat 9.0.46中Jersey-Spring API的ContextLoader重复初始化3次问题求助

分析与解决:Ubuntu Tomcat下Jersey-Spring应用重复初始化Bean的问题

Hey there, let's dig into why your identical WAR behaves differently on Ubuntu vs Windows Tomcat, and how to fix the repeated ContextLoader triggers and singleton bean instantiations.

核心现象回顾

  • 相同的Jersey-Spring WAR包,在Windows Tomcat 9.0.46运行正常,单例Bean仅初始化一次
  • 部署到Ubuntu Tomcat 9.0.46(绑定80/443端口,使用Godaddy证书)后:
    1. 第一次正常完成部署,Bean初始化完毕
    2. 等待约10分钟(对应日志中SecureRandom生成耗时)后,ContextLoader被触发两次,Bean再次初始化两次
    3. 日志中存在关键警告:Creation of SecureRandom instance for session ID generation using [SHA1PRNG] took [584,064] milliseconds

可能的原因分析

1. Ubuntu系统熵池不足导致SecureRandom阻塞(最关键)

Ubuntu默认的SecureRandom实现依赖系统熵池(用于生成安全随机数),当服务器熵值不足时,Tomcat会阻塞等待熵池填充,这直接导致了10分钟的启动延迟。在这段延迟期间,Tomcat的部署流程可能被判定为未完成,进而触发重复部署逻辑。

2. Tomcat自动部署机制重复触发

Ubuntu下Tomcat的文件系统监听器对webapps目录的变化更敏感:

  • 如果autoDeploy默认开启,WAR包解压过程中的临时文件、权限变更,甚至Tomcat运行用户的文件访问差异,都可能触发Tomcat重新检测并部署应用。
  • 延迟期间的异常状态,也可能让Tomcat认为之前的部署失败,从而重复执行部署流程。

3. 端口绑定与生命周期事件异常

绑定80/443端口时,因SecureRandom阻塞导致的启动延迟,可能干扰了Tomcat容器的生命周期事件顺序,触发了额外的上下文初始化流程。


分步解决办法

第一步:解决SecureRandom阻塞问题(优先处理)

这是导致延迟和后续连锁问题的根源,修改Tomcat的JVM参数,使用非阻塞的随机数源:

  1. 在Tomcat的bin目录下创建/编辑setenv.sh文件(Ubuntu下默认不存在),添加:
    CATALINA_OPTS="-Djava.security.egd=file:/dev/./urandom"
    

    注:/dev/./urandom是/dev/urandom的别名,避免JVM对路径的特殊解析,它会非阻塞地生成随机数,彻底解决熵池不足的问题。

  2. 重启Tomcat,验证日志中SecureRandom的警告是否消失,启动时间是否大幅缩短。

第二步:关闭Tomcat自动部署机制

避免文件系统变化触发重复部署:

  1. 打开conf/server.xml,找到对应的<Host>节点,修改配置:
    <Host name="localhost"  appBase="webapps"
          unpackWARs="true" autoDeploy="false" deployOnStartup="true">
    
    • autoDeploy="false":关闭启动后的目录监控,禁止自动重新部署
    • deployOnStartup="true":仅在Tomcat启动时一次性部署应用
  2. (可选)如果想彻底隔离自动部署,可以将WAR包移到webapps外的目录,通过自定义上下文配置加载:
    在conf/Catalina/localhost/skd-service.xml中添加:
    <Context docBase="/path/to/your/skd-service.war" reloadable="false"/>
    

第三步:检查文件权限与目录一致性

确保Ubuntu下Tomcat运行用户(通常是tomcat用户)对以下路径有完整权限:

  • WAR包所在目录
  • webapps目录
  • Tomcat的temp和work目录
    权限不足可能导致解压或文件写入失败,触发Tomcat的重复部署重试逻辑。

第四步:排除Spring/Jersey配置重复

虽然Windows下正常,但可以快速排除配置问题:

  • 检查web.xml中是否重复注册了ContextLoaderListener
  • 确认Spring的@Configuration类没有重复的@ComponentScan路径
  • 检查Jersey与Spring的集成配置(如SpringConfig)是否存在重复加载逻辑

验证效果

完成上述配置后,重启Tomcat:

  1. 启动时间应大幅缩短(不再有10分钟延迟)
  2. 日志中应仅出现一次Root WebApplicationContext initialized的信息
  3. 单例Bean仅初始化一次,不再出现重复实例化的情况

内容的提问来源于stack exchange,提问作者Eng. Samir Fares

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.29 18:32:31