暴力关机与优雅关机

2,003 阅读3分钟

1.前言

业务系统版本迭代的过程中避免不了要对应用程序进行关机操作,关机可以分为暴力关机和优雅关机,它们之间的区别会通过如下简单示例来进行演示

@GetMapping("/gracefulShutdown")
public String gracefulShutdown() throws InterruptedException {
    TimeUnit.SECONDS.sleep(20);
    log.info("关闭应用,任务可以继续执行....");
    return "关闭应用,任务可以继续执行....";
}

2.暴力关机

启动服务,通过浏览器访问:http://localhost:8080/gracefulShutdown,查看8080端口对应的pid,使用kill -2 pid命令杀掉对应进程

杀掉进程之后浏览器会出现如下效果:

控制台会出现如下效果:

2020-11-20 13:40:03.808  INFO 57565 --- [nio-8080-exec-1] com.boot.example.filter.RequestFilter    : 请求路径:http://localhost:8080/gracefulShutdown
2020-11-20 13:40:03.823  INFO 57565 --- [nio-8080-exec-1] c.b.example.controller.DebugController   : 任务开始执行....
Disconnected from the target VM, address: '127.0.0.1:51558', transport: 'socket'

Process finished with exit code 130 (interrupted by signal 2: SIGINT)

通过上面的观察可以看出,杀掉应用进程之后未执行完的请求并不会继续执行

3.优雅关机

在演示优雅关机之前,需要在配置文件中添加如下配置:

server:
  shutdown: graceful

杀掉应用进程后浏览器会出现如下效果:

控制台会出现如下效果:

2020-11-20 13:51:23.652  INFO 57943 --- [nio-8080-exec-3] com.boot.example.filter.RequestFilter    : 请求路径:http://localhost:8080/gracefulShutdown
2020-11-20 13:51:23.653  INFO 57943 --- [nio-8080-exec-3] c.b.example.controller.DebugController   : 任务开始执行....
2020-11-20 13:51:27.335  INFO 57943 --- [extShutdownHook] o.s.b.w.e.tomcat.GracefulShutdown        : Commencing graceful shutdown. Waiting for active requests to complete
2020-11-20 13:51:43.657  INFO 57943 --- [nio-8080-exec-3] c.b.example.controller.DebugController   : 关闭应用,任务可以继续执行....
2020-11-20 13:51:43.672  INFO 57943 --- [tomcat-shutdown] o.s.b.w.e.tomcat.GracefulShutdown        : Graceful shutdown complete
Disconnected from the target VM, address: '127.0.0.1:52344', transport: 'socket'

Process finished with exit code 130 (interrupted by signal 2: SIGINT)

可以看到想要实现优雅关机,只需要在配置文件中指定服务关机类型为优雅方式。优点:处于激活状态的请求会在关机之后继续被执行

4.官方说明

下面来看看SpringBoot2.3官方文档对优雅关机的说明:

大致意思就是优雅关机特性适用于4中内嵌的web服务,当关闭应用程序的时候,已经存在的请求会继续被执行并且不会接受新的请求。

上面提到在关闭应用程序之后会继续执行已经存在的请求,那么已经存在的请求会一直执行下去嘛?继续看看官方的说明:

可以看到,已存在请求的执行会有一个超时时间

超时时间配置:

spring:
  lifecycle:
    timeout-per-shutdown-phase: 60s

默认超时时间为30s