优雅的结束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代码层面来关闭服务,不仅可以关闭服务,还可以在服务关闭前后约定一些特殊的逻辑,比如:关闭前备份一些数据、或者关闭之后发送一条邮件给运维管理员等逻辑。

参考

https://mp.weixin.qq.com/s/m2WLuTPKyKeaaObPvEfHmw

posted @ 2021-05-14 22:05  不止吧  阅读(3196)  评论(0编辑  收藏  举报