什么是优雅停机?
在现代微服务架构中,优雅停机(Graceful Shutdown)是保障服务稳定性的关键环节。它的核心目标是在服务关闭时:
- 允许当前的处理请求在指定的宽限期内完成。
- 阻止新的请求进入。
- 向外部监控或负载均衡器标记服务为不可用。
这种机制能有效避免维护或升级时的数据丢失和请求中断,提升系统的整体可用性。
Spring Boot 3 优雅停机的配置
Spring Boot 3 内置了对优雅停机的支持,只需修改配置文件即可启用。主要涉及两个关键参数:
server:
shutdown: graceful # 开启优雅停机模式
spring:
lifecycle:
timeout-per-shutdown-phase: 20s # 停机的宽限期,默认为 30 秒
此配置适用于所有四种嵌入式 Web 服务器(Tomcat、Jetty、Reactor Netty 和 Undertow)。需要注意的是,Spring Boot 3 默认禁用优雅停机,必须显式将 server.shutdown 设置为 graceful 才能生效。
Tomcat 和 Reactor Netty 的优雅停机机制
不同的 Web 服务器底层实现略有差异,但核心逻辑一致。
Tomcat 优雅停机
使用 Tomcat 9.0.33 及以上版本时,启用优雅停机后,当收到关闭信号,它会在网络层停止接受新的连接请求,并阻断传入流量。Tomcat 会确保已有请求在宽限期内完成,若超时则强制终止。
Reactor Netty 优雅停机
作为 Spring WebFlux 默认的响应式服务器,Reactor Netty 通过非阻塞模型实现无缝停机。关闭信号到达后,它立即停止接受新连接,并在宽限期内继续处理活动请求,超时后释放资源。
优雅停机的流程
无论是 Tomcat 还是 Reactor Netty,其停机流程大致遵循以下步骤:
- 标记服务不可用:通常由负载均衡器剔除实例或在网络层阻断连接,防止新流量进入。
- 设置宽限期:当前请求允许在配置的时间内继续处理。
- 关闭活动连接:宽限期结束后,未完成的请求被中止,资源释放。
Spring Boot 3 内部通过 SmartLifecycle 和 ApplicationContext 控制器管理生命周期,确保组件按顺序停止。
实现优雅停机的完整示例
我们可以通过一个简单的应用来验证配置效果。
代码示例
在 application.yml 中启用配置:
server:
shutdown: graceful
spring:
lifecycle:
timeout-per-shutdown-phase: 30s
创建一个模拟耗时任务的 REST 控制器:
@RestController
@RequestMapping("/api")
public class DemoController {
@GetMapping("/long-running")
public String longRunningTask() throws InterruptedException {
System.out.println("开始执行耗时任务...");
Thread.sleep(20000); // 模拟耗时任务
return "任务完成";
}
}
为了便于测试,可以在启动类中添加销毁钩子:
@PreDestroy
public void destroy() {
System.out.println("Application is destroyed");
}
本地调试与测试
直接在 IDE 点击停止按钮往往无法模拟真实的停机信号,因此推荐使用 Actuator 端点进行测试。添加依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
配置暴露端点:
management:
endpoints:
web:
exposure:
include: '*'
endpoint:
shutdown:
enabled: true
调用 curl -X POST http://localhost:8080/actuator/shutdown 即可触发停机流程。如果请求在宽限期内,会返回'任务完成';若超过宽限期,请求将被强制中止。
负载均衡器中的停机策略
在生产环境中,仅靠应用层配置还不够。建议配合负载均衡器(如 Nginx、Kubernetes)使用。当服务准备停机时,先从负载均衡池中剔除该实例,确保新流量不再转发到该节点,随后再发送关闭信号。这样能确保所有请求被其他实例接管,当前实例只处理已有请求直至完成。
优雅停机的注意事项
- 宽限期配置:需根据业务最长请求时间合理设置,避免因过短导致任务中断。
- 负载均衡器协作:务必确认负载均衡器的健康检查与摘除机制已生效。
- 避免频繁重启:高负载下频繁停机会影响用户体验,应规划好维护窗口。
总结
Spring Boot 3 通过简单的配置即可实现优雅停机,有效减少服务关闭对用户体验的影响。Tomcat 和 Reactor Netty 均采用在网络层阻止新请求、应用层设置宽限期的方式。在高并发微服务架构中,结合负载均衡策略正确配置优雅停机,是保持系统稳定性和一致性的必要手段。

