springboot优雅的关闭应用
SpringBoot应用 关闭 优雅
2023-09-27 14:24:47 时间
- 使用actuator,通过发送http请求关闭
- 将应用注册为linux服务,通过service xxx stop关闭
具体这两种方式如何实现,这里就不说了,网上百度一堆,主要讲一下在这两种情况下web应用listener的一些问题
一般来讲,我们的应用都应该在结束的时候对资源进行回收处理,jvm帮我们做了一部分,springboot也做了相应bean的回收,那如果是我们自己创建的线程池或是其他未托管于spring的资源呢?
-
在非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 + <span class="hljs-string">"_shutdown_hook_thread"</span>));</pre> </li>
-
在web应用中,勾子就不一定能够生效了,而是通过实现ServletContextListener接口,可以在context初始化和结束的时候做一些资源创建和回收的操作
public class ContextListener implements ServletContextListener { private static final Logger LOGGER = LoggerFactory.getLogger(ContextListener.class);
<span class="hljs-annotation">@Override</span> <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">contextInitialized</span><span class="hljs-params">(ServletContextEvent servletContextEvent)</span> </span>{ LOGGER.info(<span class="hljs-string">"contextInitialized"</span>); } <span class="hljs-annotation">@Override</span> <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">contextDestroyed</span><span class="hljs-params">(ServletContextEvent servletContextEvent)</span> </span>{ LOGGER.info(<span class="hljs-string">"contextDestroyed begin..."</span>); ShutdownUtil.destroy(); LOGGER.info(<span class="hljs-string">"contextDestroyed end..."</span>); } }</pre> </li>
问题来了,在使用第二种方式将springboot应用注册为linux服务时,发现通过service xxx stop命令停止应用时,contextDestroyed的日志根本没打印出来,怀疑是LOGGER对象已经被jvm回收,于是改成System.out,这次begin打印出来了,但是并没有调用 ShutdownUtil.destroy()方法,怀疑同上,具体的机制没去详细了解,猜测是springboot自己的回收策略,或者是该插件的坑。
使用actuator的方式没有问题,会正常的执行destroyed的回收
相关文章
- 实现SpringBoot项目的多数据源配置的两种方式(dynamic-datasource-spring-boot-starter和自定义注解的方式)
- 精品springboot英语知识应用网站在线学习知识分享下载
- 第十七章 springboot + devtools(热部署)
- 学习SpringBoot:阿里巴巴java工程师工资
- SpringBoot RedisCacheConfig自定义设置
- Springboot 整合RabbitMq ,用心看完这一篇就够了
- SpringBoot 教程之 profile 的应用
- [SrpingBoot]初步搭建springboot应用,报错:Failed to configure a DataSource: 'url' attribute is not specified and no embedd[转载]
- SpringBoot --web 应用开发之文件上传
- idea打包SpringBoot项目打包成jar包和war
- SpringBoot学习:整合shiro(身份认证和权限认证),使用EhCache缓存(转)
- Springboot整合Websocket案例(后端向前端主动推送消息)
- springboot 获取Resource目录下的文件
- springboot jpa使用
- springboot防止XSS攻击和sql注入
- SpringBoot使用阿里云oss实现文件上传
- SpringBoot笔记——员工管理
- SpringBoot源码解析之应用类型识别