Spring Boot Web Server 在 2.3.x 后支持优雅停机,可以通过三种枚举配置,对应配置项为 server.shutdown
public enum GracefulShutdownResult {
/**
* Requests remained active at the end of the grace period.
*/
REQUESTS_ACTIVE,
/**
* The server was idle with no active requests at the end of the grace period.
*/
IDLE,
/**
* The server was shutdown immediately, ignoring any active requests.
*/
IMMEDIATE;
}
WebServer
AbstractApplicationContext#onRefresh
ServletWebServerApplicationContext#onRefresh
createWebServer
ReactiveWebServerApplicationContext#onRefresh
createWebServer
不论是 Servlet 分支还是 Reactive 分支,创建时都会注册两个单例 Bean:WebServerStartStopLifecycle 和 WebServerGracefulShutdownLifecycle,两者均实现了 Spring Bean 生命周期接口 SmartLifecycle,SmartLifecycle#stop(Callback) 在 JVM 停机时会被调用(callback 最先由 LifeCycleProcessor 传递,被 web 层包装为 GracefulShutdownCallback)。
WebServerStartStopLifecycle 持有 WebServer 引用,负责 WebServer 起停。
在 start cycle 调用 WebServer#start 启动 WebServer 并发布事件 ServletWebServerInitializedEvent。
在 stop cycle 调用 WebServer#stop 开始关闭 WebServer。
WebServerGracefulShutdownLifecycle 也持有 WebServer 引用
在 stop cycle 调用 WebServer#shutDownGracefully 执行优雅停机。
@Override
public void stop(Runnable callback) {
this.running = false;
this.webServer.shutDownGracefully((result) -> callback.run());
}
各 WebServer 会实现自己的 stop 逻辑和 shutDownGracefully 方法,前者一般会调用嵌入式 server 的停机方法,必要时会和 shutDownGracefully 逻辑互动。
各 WebServer 收到 shutDownGracefully 调用后,通用做法是:
shutDownGracefully 通用做法都是启动线程异步无限等待 WebServer 请求队列清空。