当前位置: 首页 > news >正文

一次生产环境 Tomcat 7 + JDK 7 应用启动失败的完整排查与修复实录 - 指南

一次生产环境 Tomcat 7 + JDK 7 应用启动失败的完整排查与修复实录 - 指南

文章目录

  • 一次生产环境 Tomcat 7 + JDK 7 应用启动失败的完整排查与修复实录
    • 一、问题初现:看似成功,实则崩溃
    • 二、第一步:解决端口冲突(表面问题)
      • 定位占用进程
      • ️ 强制清理
      • ✅ 验证重启
    • 三、第二步:修复内存泄漏(根本问题)
      • 1. JDBC 驱动未注销
      • 2. MySQL 后台线程未停
      • 3. Quartz 工作线程泄漏(最严重)
      • ️ 解决方案:添加全局销毁监听器
    • 四、第三步:修复 Ehcache RMI 集群配置
      • ✅ 正确做法
      • 开放防火墙
    • 五、其他优化项
      • 1. 解决 SLF4J 多绑定冲突
      • 2. 移除 WEB-INF/lib 中的 servlet-api.jar
    • 六、最终验证
    • 七、经验总结

一次生产环境 Tomcat 7 + JDK 7 应用启动失败的完整排查与修复实录

环境:CentOS 7 + Tomcat 7.0.96 + JDK 1.7.0_80 + Ehcache 2.6 + Memcached
应用:Spring MVC 项目 /dhmall,含 Quartz 定时任务、Druid 数据源、RabbitMQ、银联支付 SDK
问题现象:Tomcat 启动后立即崩溃,报 Address already in use,伴随大量内存泄漏警告

本文将完整复盘从日志分析、端口冲突解决到资源泄漏修复的全过程,为同类老旧 Java 系统提供排错参考。


一、问题初现:看似成功,实则崩溃

首次查看日志时,被这行迷惑:

INFO: Server startup in 23868 ms

但紧接着出现致命错误:

SEVERE: StandardServer.await: create[localhost:8088]:
java.net.BindException: Address already in use

随后 Tomcat 自动进入 shutdown 流程,并暴露出一系列严重警告:

SEVERE: The web application [] registered the JDBC driver [...] but failed to unregister it
SEVERE: The web application [] appears to have started a thread named [schdulerFactory_Worker-1]...

结论:这不是简单的“端口占用”,而是 残留进程 + 资源泄漏 的复合型故障。


二、第一步:解决端口冲突(表面问题)

定位占用进程

# 查找占用 8088 或 8005 端口的进程
lsof -i :8088
lsof -i :8005
# 输出示例
java    12345 user ... /apache-tomcat-7.0.96/...

️ 强制清理

kill -9 12345
# 再次检查确保无残留
netstat -tulnp | grep -E '8088|8005'

经验:在频繁部署或异常断电后,Tomcat 进程常“假死”残留,务必手动清理。

✅ 验证重启

/data/soft/apache-tomcat-7.0.96/bin/startup.sh
tail -f logs/catalina.out

此时 Tomcat 成功启动,HTTP 服务可访问。但隐患仍在


三、第二步:修复内存泄漏(根本问题)

尽管应用能运行,但每次重启都会留下“垃圾”,长期将导致 Metaspace OOM。日志中三大泄漏点:

1. JDBC 驱动未注销

SEVERE: ... registered the JDBC driver [com.alibaba.druid.proxy.DruidDriver] but failed to unregister

2. MySQL 后台线程未停

SEVERE: ... thread named [MySQL Statement Cancellation Timer] ...

3. Quartz 工作线程泄漏(最严重)

SEVERE: ... thread named [schdulerFactory_Worker-1] ... memory leak

️ 解决方案:添加全局销毁监听器

创建 AppCleanupListener.java

package com.dhmall.listener;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import net.sf.ehcache.CacheManager;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;
public class AppCleanupListener implements ServletContextListener {
@Override
public void contextDestroyed(ServletContextEvent sce) {
WebApplicationContext ctx = WebApplicationContextUtils.getWebApplicationContext(sce.getServletContext());
// 1. 关闭 Quartz 调度器
try {
Scheduler scheduler = (Scheduler) ctx.getBean("schdulerFactory");
if (scheduler != null && !scheduler.isShutdown()) {
scheduler.shutdown(true); // 等待任务完成
}
} catch (Exception e) {
e.printStackTrace();
}
// 2. 关闭 Ehcache(如有集群,会自动注销 RMI)
try {
CacheManager.getInstance().shutdown();
} catch (Exception e) {
e.printStackTrace();
}
// 3. (可选)显式注销 JDBC 驱动(新版通常自动处理)
// DriverManager.deregisterDriver(...);
}
@Override
public void contextInitialized(ServletContextEvent sce) {
// 初始化逻辑(如设置 RMI hostname)
System.setProperty("java.rmi.server.hostname", "172.26.100.204");
}
}

web.xml 中注册:

<listener>
<listener-class>com.dhmall.listener.AppCleanupListener</listener-class>
</listener>

效果:应用停止时,Quartz 线程池优雅关闭,Ehcache 断开 RMI 连接,JDBC 驱动被清理。


四、第三步:修复 Ehcache RMI 集群配置

原配置存在致命错误:

<cacheManagerPeerListenerFactoryproperties="hostName=localhost, port=40001, ..." />

hostName=localhost 导致其他节点无法连接!

✅ 正确做法

  1. 移除 hostName 配置
  2. 通过 JVM 参数指定对外 IP

tomcat/bin/setenv.sh(若无则新建)中添加:

export CATALINA_OPTS="$CATALINA_OPTS -Djava.rmi.server.hostname=172.26.1.2"

ehcache.xml 简化为:

<cacheManagerPeerListenerFactoryclass="net.sf.ehcache.distribution.RMICacheManagerPeerListenerFactory"properties="port=40001, socketTimeoutMillis=2000" />

开放防火墙

firewall-cmd --permanent --add-port=40001/tcp
firewall-cmd --reload

五、其他优化项

1. 解决 SLF4J 多绑定冲突

日志中:

SLF4J: Class path contains multiple SLF4J bindings.

pom.xml 中排除冗余绑定:

<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-jdk14</artifactId>
</exclusion>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
</exclusion>

2. 移除 WEB-INF/lib 中的 servlet-api.jar

validateJarFile(.../servlet-api-2.5.jar) - jar not loaded.

该 JAR 应由 Tomcat 提供,应用中不应包含。


六、最终验证

  1. 正常启动:无 BindExceptionServer startup in XXX ms 后持续运行
  2. 无泄漏警告:重启时不再出现 SEVERE: ... memory leak
  3. 集群同步:多节点环境下缓存更新实时生效
  4. 外部可访问curl http://服务器IP:8088/dhmall/xxx 返回正常

七、经验总结

问题类型教训
端口冲突永远先查 lsof,不要被“startup”迷惑
线程泄漏所有后台线程(Quartz/Ehcache/Timer)必须显式关闭
RMI 配置hostName=localhost 是集群最大陷阱
老旧技术栈JDK 7 + Tomcat 7 已 EOL,建议尽快升级

最后忠告:对于仍在使用 JDK 7/Tomcat 7 的系统,请务必建立完善的启停脚本和健康检查机制。技术债终需偿还,但在此之前,我们仍要守护好每一行 legacy code 的稳定运行。

http://www.jsqmd.com/news/99792/

相关文章:

  • LobeChat本地安装详细教程
  • 2025年专业起名老师联系方式汇总:全国资深专家联系通道与科学咨询指引 - 品牌推荐
  • 2025年低泡润湿分散剂供货厂家权威推荐榜单:润湿分散剂/抑泡润湿分散剂/环保润湿剂源头厂家精选 - 品牌推荐官
  • 2025年年终太原管道疏通推荐:权威榜单TOP10及核心服务对比分析 - 品牌推荐
  • LobeChat能否接入LinkedIn API?职业发展建议机器人
  • 2025年年终柳州管道疏通推荐:综合排名比较与真实用户评测报告 - 十大品牌推荐
  • waitGroup底层源码分析
  • 2025年宝宝起名老师联系方式汇总:全国资深专家官方联系通道与科学选择指引 - 品牌推荐
  • 2025年起名老师联系方式汇总:全国资深专家联系通道与专业起名服务指引 - 品牌推荐
  • 2025年起名老师联系方式汇总:全国资深专家官方联系通道与专业起名服务指引 - 品牌推荐
  • TensorFlow-GPU环境搭建与PyCharm配置
  • 2025年年终柳州管道疏通推荐:权威排名与用户真实评价汇总 - 十大品牌推荐
  • 2025年年终太原管道疏通推荐:专业排行解析与多维度服务对比指南 - 品牌推荐
  • 2025年公司取名公司联系方式汇总: 全国主要服务机构官方联系方式及专业合作指引 - 品牌推荐
  • 2025年年终合肥管道疏通推荐:专业排行解析与多维度对比评测 - 品牌推荐
  • 2025广东最新AI搜索/GEO/AI营销服务推荐!东莞等企业智能转型优选方案发布,技术赋能驱动数字化升级 - 全局中转站
  • 2025年12月陕西钢质/木质/通用防火门厂家优选榜TOP5:五家企业合规实力双在线 - 深度智识库
  • Jenkins备份及回滚方式
  • LobeChat能否用于编写Prometheus告警规则?可观测性增强
  • 2025年公司起名公司联系方式汇总: 全国专业机构核心联系方式与品牌命名决策参考 - 品牌推荐
  • 家用制氧机选哪个好?老人用、术后用、高原用制氧机真实评测与选购指南 - 速递信息
  • 2025年年终柳州管道疏通推荐:专业排行解析与多维度服务对比指南 - 十大品牌推荐
  • LobeChat能否隐藏源码信息?增强系统隐蔽性
  • 2025年专业起名老师联系方式汇总:全国资深专家联系通道与高效咨询 - 品牌推荐
  • 2025年专业起名老师联系方式汇总:全国资深专家联系通道与高效咨询指引 - 品牌推荐
  • 可视化总结,AI在培训/咨询/共创/讨论/会议……场景的小实践
  • 飞腾D3000安装debian12后无法加载RTL8852BE驱动的问题处理
  • Dify与Anything-LLM整合构建企业级AI助手
  • 2025年年终太原管道疏通推荐:权威榜单解析与多维度服务对比评测 - 品牌推荐
  • LobeChat能否绑定微信支付?小程序联动设想