优雅的结束springboot服务的3种方式
前言
我们使用linux时,终止程序一般喜欢用 kill -9 pid
命令,因为这个命令来的快,执行及终止,不需要等待。我也一直喜欢用这个命令,包括在写一些程序关闭脚本时,也用的这个命令,其实也不是不知道这个命令的弊端,但平时做的项目太小并发不高,出现这个问题的概率太小。今天无意看到一篇文章《CTO 说了,如果发现谁用 kill -9 关闭程序就开除》,深有感触。以下是优雅的结束springboot服务的3种方式:
什么叫优雅的结束?
第一步:停止接收请求和内部线程。
第二步:判断是否有线程正在执行。
第三步:等待正在执行的线程执行完毕。
第四步:停止容器。
第一种:kill -15 pid
kill -15 这个命令会让程序马上调用线程的interrupt方法,目的是为了让线程停止,虽然让线程停止,但线程什么时候停止还是线程自己说的算
第二种:ConfigurableApplicationContext colse
@PostMapping(value = "shutdown")
public void shutdown(){
ConfigurableApplicationContext cyx = (ConfigurableApplicationContext) context;
cyx.close();
}
cyx.close();
,为什么他能停止springboot项目呢?
public void close() {
synchronized(this.startupShutdownMonitor) {
this.doClose();
if (this.shutdownHook != null) {
try {
Runtime.getRuntime().removeShutdownHook(this.shutdownHook);
} catch (IllegalStateException var4) {
}
}
}
}
程序在启动的时候向jvm注册了一个关闭钩子,我们在执行colse方法的时候会删除这个关闭钩子,jvm就会知道这是需要停止服务。jvm执行了线程的interrupt方法,原理和kill -15差不多。
第三种:actuator
这种方式是通过引入依赖的方式停止服务,actuator提供了很多接口,比如健康检查,基本信息等等,我们也可以使用他来优雅的停机。请求地址类似http:/domain/actuator/shutdown
小记
通过java代码层面来关闭服务,不仅可以关闭服务,还可以在服务关闭前后约定一些特殊的逻辑,比如:关闭前备份一些数据、或者关闭之后发送一条邮件给运维管理员等逻辑。