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 请求队列清空。

tomcat shutdown