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

Tomcat 7每日凌晨3点服务暂不可用问题排查求助

问题原因分析
  • ThreadLocal内存泄漏:ThreadLocal未正确清理会导致Tomcat线程池中的线程持有对象引用,内存无法被GC回收。长期积累后,凌晨时段(内存耗尽的临界点)引发OutOfMemoryError,导致Tomcat服务假死或崩溃,表现为“服务暂时不可用”。
  • Mojarra运行时销毁异常:作为JSF实现,Mojarra在容器生命周期销毁阶段出现异常,通常是资源未正确释放(如数据库连接、IO流)或版本与Tomcat不兼容,导致容器资源无法正常回收,加剧内存泄漏或服务不稳定。
  • 端口占用:服务崩溃后Tomcat进程未完全退出,残留进程占用8080/8443/8009端口;你提到重启后恢复,大概率是重启操作强制终止了残留进程,但根源还是内存泄漏导致服务异常退出。
解决方案

针对ThreadLocal内存泄漏

  • 遍历代码中所有ThreadLocal实例,确保在请求结束、线程复用前调用remove()方法,建议在过滤器、拦截器的finally块中统一清理,避免遗漏。
  • 启用Tomcat线程池监控(通过conf/server.xml配置线程池maxThreads、minSpareThreads并结合JMX监控),跟踪线程数量和内存占用变化趋势,定位泄漏源头。
  • 利用内存分析工具(如MAT)抓取凌晨服务崩溃前的内存快照,分析对象引用链,找到未被释放的ThreadLocal所属类,针对性修复。

针对Mojarra销毁异常

  • 核对Mojarra与Tomcat的版本兼容性,比如Mojarra 2.3.x需搭配Tomcat 8.5及以上版本,升级到双方适配的稳定版本。
  • 检查JSF后台Bean的资源使用情况,确保在@PreDestroy方法中关闭数据库连接、IO流等资源,避免残留引用。
  • 在web.xml中添加Mojarra的清理配置,强制销毁时清理所有资源:
    <context-param>
        <param-name>com.sun.faces.cleanupOnDestroy</param-name>
        <param-value>true</param-value>
    </context-param>
    

针对端口占用问题

  • 修改Tomcat关闭脚本,添加强制终止残留进程的逻辑:
    • Linux:在shutdown.sh末尾加入pkill -f "catalina"或kill -9 $(lsof -t -i:8080)
    • Windows:在shutdown.bat中添加taskkill /F /IM java.exe
  • 编写定时监控脚本,凌晨时段检测服务状态,若出现“服务暂时不可用”,先清理占用端口的进程再自动重启Tomcat。
  • 临时调整Tomcat端口(修改conf/server.xml中的Connector端口配置),但这只是缓解手段,需优先解决内存泄漏问题。

内容的提问来源于stack exchange,提问作者Hermano Barradas

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 18:12:37