springboot优雅的关闭应用

本文探讨了SpringBoot应用中资源回收的问题,特别是在使用actuator和作为Linux服务时的关闭过程。通过实现ServletContextListener接口和使用Runtime ShutdownHook进行资源释放的方法被详细讨论。

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

  1. 使用actuator,通过发送http请求关闭
  2. 将应用注册为linux服务,通过service xxx stop关闭

具体这两种方式如何实现,这里就不说了,网上百度一堆,主要讲一下在这两种情况下web应用listener的一些问题

一般来讲,我们的应用都应该在结束的时候对资源进行回收处理,jvm帮我们做了一部分,springboot也做了相应bean的回收,那如果是我们自己创建的线程池或是其他未托管于spring的资源呢?

  1. 在非web的应用中,我们一般使用勾子来实现,从而保证在jvm退出时,能够进行一些资源的回收(直接kill无法保证执行),kill命令相当于直接把应用干掉,是一种非正常情况下中止应用的方式。ctrl+c,System.exit(),程序正常退出都会触发勾子

    		Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {
    	            @Override
    	            public void run() {
    	                try {
    	                    shutdown(componentName);
    	                } catch (Exception e) {
    	                    LOGGER.error("shutdown error:", e);
    	                }
    
    	            }
    	        }, componentName + "_shutdown_hook_thread"));
    
    
  2. 在web应用中,勾子就不一定能够生效了,而是通过实现ServletContextListener接口,可以在context初始化和结束的时候做一些资源创建和回收的操作

    	public class ContextListener implements ServletContextListener {
    	    private static final Logger LOGGER = LoggerFactory.getLogger(ContextListener.class);
    
    	    @Override
    	    public void contextInitialized(ServletContextEvent servletContextEvent) {
    	        LOGGER.info("contextInitialized");
    	    }
    
    	    @Override
    	    public void contextDestroyed(ServletContextEvent servletContextEvent) {
    	        LOGGER.info("contextDestroyed begin...");
    	        ShutdownUtil.destroy();
    	        LOGGER.info("contextDestroyed end...");
    	    }
    	}
    

问题来了,在使用第二种方式将springboot应用注册为linux服务时,发现通过service xxx stop命令停止应用时,contextDestroyed的日志根本没打印出来,怀疑是LOGGER对象已经被jvm回收,于是改成System.out,这次begin打印出来了,但是并没有调用 ShutdownUtil.destroy()方法,怀疑同上,具体的机制没去详细了解,猜测是springboot自己的回收策略,或者是该插件的坑。

使用actuator的方式没有问题,会正常的执行destroyed的回收

转载于:https://my.oschina.net/zjoschina/blog/1512053

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值