TOMCAT下shutdown不能完全关闭的解决方法

本文介绍了一种在Java Web应用中实现优雅关闭的方法,通过在ServletContextListener中添加特定逻辑来确保服务停止时能够正确地关闭线程和JDBC驱动,避免了直接使用kill-9带来的问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


经常碰到shutdown之后不能完全关闭, 每次kill -9 操作麻烦且破换程序处理, 借鉴网上资料作下整理:

1. ps -aux | grep 8089/bin 找到遗留的进程PID


2. 使用jdk自带的jstack pid 查看具体线程


3. ServletContextListener服务监听器的销毁方法中, 增加关闭线程的处理:

public class SystemContextListener implements ServletContextListener
{

	private static Logger logger = Logger.getLogger(SystemContextListener.class);
	
	// 需要强制关闭的线程名
	public static final List<String> MANUAL_DESTROY_THREAD_IDENTIFIERS = Arrays.asList("QuartzScheduler", "scheduler_Worker", "miiapQuartzFactory_QuartzSchedulerThread", "MultiThreadedHttpConnectionManager cleanup");  
	
	@Override
	public void contextDestroyed(ServletContextEvent contextEvent) {

		// 关闭T2接口服务
		T2Interface.stop();

		destroyJDBCDrivers();
		destroySpecifyThreads();

		
	}

	@Override
	public void contextInitialized(ServletContextEvent contextEvent)
	{

		try
		{
			
			// 初始化spring容器
			SpringBeanFactory.init("classpath*:application*.xml");
			
			// 初始化, 读取系统配置
			ConfigProperties.initALL();
			
			
			// 启动T2接口服务
			T2Interface.initConfigs();
			T2Interface.start();
			


		}
		catch (Exception e)
		{
			e.printStackTrace();
			logger.error(e.getMessage(), e);
		}

	}
	
	/**
	 * 注销线程
	 */
	private void destroySpecifyThreads() {  
        final Set<Thread> threads = Thread.getAllStackTraces().keySet();  
        for (Thread thread : threads) {  
        	// 默认会把所有调度相关的线程关闭
            if (needManualDestroy(thread) || (thread.getName()!= null && thread.getName().toUpperCase().indexOf("QUARTZ")!= -1)) {  
                synchronized (this) {  
                    try {  
                        thread.stop();  
                        logger.debug(String.format("Destroy  %s successful", thread));  
                    } catch (Exception e) {  
                        logger.warn(String.format("Destroy %s error", thread), e);  
                    }  
                }  
            }  
        }  
    }  
  
	/**
	 * 需要销毁的线程名
	 * @param thread
	 * @return
	 */
    private boolean needManualDestroy(Thread thread) {  
        final String threadName = thread.getName();  
        for (String manualDestroyThreadIdentifier : MANUAL_DESTROY_THREAD_IDENTIFIERS) {  
            if (threadName.contains(manualDestroyThreadIdentifier)) {  
                return true;  
            }  
        }  
        return false;  
    }  
  
    /**
     * 注销JDBC驱动
     */
    private void destroyJDBCDrivers() {  
        final Enumeration<Driver> drivers = DriverManager.getDrivers();  
        Driver driver;  
        while (drivers.hasMoreElements()) {  
            driver = drivers.nextElement();  
            try {  
                DriverManager.deregisterDriver(driver);  
                logger.debug(String.format("Deregister JDBC driver %s successful", driver));  
            } catch (SQLException e) {  
                logger.warn(String.format("Deregister JDBC driver %s error", driver), e);  
            }  
        }  
    }  


}




Tomcat是一个开源的Java Web服务器,它是Apache软件基金会的一个项目。当我们停止Tomcat服务器时,可能会遇到Tomcat shutdown进程仍在运行的情况。 出现这种情况通常是由于某些正在运行的任务或线程没有正确关闭所致。在关闭Tomcat服务器时,Tomcat会尝试结束所有正在运行的任务和线程,然后关闭自身。但有时候,如果存在某些无法正常结束的任务或线程,就会导致Tomcat shutdown进程仍然存在。 要解决这个问题,我们可以尝试以下几种方法: 1. 查找并终止相关的进程:使用任务管理器或命令行工具,查找并手动终止与Tomcat相关的进程。通常可以通过进程名称或进程ID来识别。终止这些进程后,Tomcat shutdown进程应该会消失。 2. 强制关闭进程:如果无法通过常规方法终止Tomcat shutdown进程,我们可以尝试使用`kill`命令(在UNIX或Linux系统上)或`taskkill`命令(在Windows系统上)来强制关闭该进程。这需要在命令行中执行相应的命令,并提供Tomcat shutdown进程的进程ID。 3. 检查Tomcat日志文件:查看Tomcat服务器的日志文件,例如catalina.out或catalina.log,以获取关于无法正常关闭的任务或线程的更多信息。根据日志中的报错信息,可以尝试修复相关的问题,并重新启动Tomcat服务器。 总的来说,当Tomcat shutdown进程仍然存在时,我们可以尝试通过手动终止相关进程、强制关闭进程以及检查Tomcat日志文件来解决该问题。这些方法将帮助我们确保Tomcat服务器完全关闭,并可以重新启动或进行其他需要操作。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

麦神-mirson

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值