首页 > 解决方案 > Spring boot app gracefully catch the SIGTERM signal and invoke the predestroy method

问题描述

I have a spring boot application which needs to clear or clean up the resources when we kill the process using kill pid. @predestroy annotated method is not working and not getting called. Please suggest how can we catch the SIGTERM and invoke the predestroy method

标签: springspring-boot

解决方案


理想情况下,它应该可以工作,但要确保SIGTERM被调用而不是SIGKILL

我有一些我们运行 Spring Boot 应用程序的情况

码头工人

当您执行docker stop幕后发生的事情时

停止一个或多个正在运行的容器 容器内的主进程会收到 SIGTERM,在宽限期过后,会收到 SIGKILL

kill 9955 => SIGTERM 被调用 kill -9 9955=> SIGKILL 被调用

有关杀死的更多详细信息,请参阅此处

现在回到@PreDestroy

我在我的 SpringBoot 应用程序中添加了以下行

@PreDestroy
public void tearDown() {
    System.out.println("Shutting Down...............the ");
}

当我这样做时,我得到以下输出kill portno

2019-01-04 10:52:44.776  INFO o.s.s.c.ThreadPoolTaskScheduler / shutdown - 208 : Shutting down ExecutorService 'taskScheduler'
2019-01-04 10:52:44.783  INFO o.s.s.c.ThreadPoolTaskExecutor / shutdown - 208 : Shutting down ExecutorService 'applicationTaskExecutor'
2019-01-04 10:52:44.785  INFO o.s.o.j.LocalContainerEntityManagerFactoryBean / destroy - 597 : Closing JPA EntityManagerFactory for persistence unit 'default'
2019-01-04 10:52:44.792  INFO c.z.h.HikariDataSource / close - 350 : HikariPool-1 - Shutdown initiated...
2019-01-04 10:52:44.800  INFO c.z.h.HikariDataSource / close - 352 : HikariPool-1 - Shutdown completed.
Shutting Down...............

正如您在日志中看到的,我有 2 个正在运行的调度程序任务和 JPA 实体管理器。收到SIGTERM它后,它首先关闭所有内容,最后调用 preDestory。

我不确定您还需要做些什么清理工作,但请确保它是否已经清理过。

优雅地关闭嵌入式 servlet 容器

您还可以自定义和编写自己的关闭优雅挂钩。 参考这个很好的讨论和示例代码

重构嵌入式 Web 服务器包

请注意上面链接中的示例代码。如果您使用的是较新版本的 Springboot,则可能缺少包。

有关更改方法和类的更多详细信息,请参阅this


推荐阅读