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