本文目录导读:

- 核心机制:
Runtime.getRuntime().addShutdownHook() - Spring Boot 原生支持(最常用)
- Spring Cloud / 微服务场景
- Web 容器级别支持
- 使用信号处理(Linux/Unix)
- 框架支持总结表
- 生产环境最佳实践
Java 对优雅停机(Graceful Shutdown)有 原生支持,且在不同版本中不断增强,主要通过在关闭时等待正在执行的任务完成、释放资源来实现,而非强制 kill -9。
以下是 Java 实现优雅停机的几种方式及版本支持情况:
核心机制:Runtime.getRuntime().addShutdownHook()
这是最基础、最通用的方式,Java 1.3+ 就开始支持。
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
System.out.println("执行优雅停机逻辑...");
// 关闭线程池、释放数据库连接、关闭文件等
executorService.shutdown();
try {
executorService.awaitTermination(10, TimeUnit.SECONDS);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}));
- 触发条件:程序正常退出、
System.exit()、Ctrl+C、SIGTERM信号 - 不触发条件:
kill -9、Runtime.halt()、JVM 崩溃
Spring Boot 原生支持(最常用)
Spring Boot 3+ 内置了对优雅停机的支持,0+ 可以通过配置实现。
1 配置方式(application.yml)
server:
shutdown: graceful # 开启优雅停机
spring:
lifecycle:
timeout-per-shutdown-phase: 30s # 最大等待时间
2 工作原理
- 停止接收新请求
- 等待当前正在处理的请求完成(不超过
timeout-per-shutdown-phase) - 触发
@PreDestroy、DisposableBean.destroy()等生命周期回调 - 最后关闭容器
3 代码中监听停机事件
@Component
public class GracefulShutdownListener {
@EventListener
public void onShutdown(ContextClosedEvent event) {
System.out.println("应用正在关闭,执行清理...");
// 关闭自定义线程池、连接池等
}
}
Spring Cloud / 微服务场景
对于微服务架构,需要配合注册中心实现服务下线通知:
@PreDestroy
public void deregisterFromRegistry() {
// 1. 从 Eureka / Nacos 等注册中心下线
// 2. 等待一段时间让负载均衡器感知(5-10s)
// 3. 再关闭容器
}
工具推荐:
- Spring Cloud 的
spring-cloud-starter-netflix-eureka-client自带优雅下线逻辑
Web 容器级别支持
1 Tomcat(Spring Boot 内嵌)
Spring Boot 2.3+ 通过 ServletWebServerFactory 自动配置了优雅停机。
手动配置(更低层级):
@Bean
public GracefulShutdown tomcatGracefulShutdown(TomcatServletWebServerFactory factory) {
GracefulShutdown gracefulShutdown = new GracefulShutdown();
factory.addConnectorCustomizers(connector -> {
connector.addLifecycleListener(gracefulShutdown);
});
return gracefulShutdown;
}
2 Undertow(高性能场景)
server: shutdown: graceful
Undertow 的优雅停机性能通常优于 Tomcat。
使用信号处理(Linux/Unix)
Java 可以捕获操作系统信号(如 SIGTERM)来实现更精细的控制:
Signal.handle(new Signal("TERM"), signal -> {
System.out.println("收到 SIGTERM,开始优雅关闭...");
// 你的关闭逻辑
System.exit(0);
});
注意:JDK 9+ 对信号处理更加稳定。
框架支持总结表
| 方式 | 支持版本 | 适用场景 | 是否需要额外代码 |
|---|---|---|---|
| ShutdownHook | Java 1.3+ | 通用、简单应用 | 需要写回调逻辑 |
| Spring Boot | 3+(配置)、全版本(代码) | Spring 应用 | 只需配置或 @EventListener |
| Tomcat | 嵌入式 9+ | Web 应用 | Spring Boot 自动配置 |
| 信号处理 | Java 所有版本 | Linux 部署、容器环境 | 需要注册 SignalHandler |
| Spring Cloud | 长期支持 | 微服务 | 需配合注册中心 |
生产环境最佳实践
# 1. 开启优雅停机
server.shutdown: graceful
spring.lifecycle.timeout-per-shutdown-phase: 30s
# 2. Dockerfile 中确保使用 SIGTERM 而不是 SIGKILL
STOPSIGNAL SIGTERM
# 3. Kubernetes 中配置 preStop hook(额外保障)
lifecycle:
preStop:
exec:
command: ["/bin/sh", "-c", "sleep 10 && kill -15 1"]
核心检查清单:
- ✅ 线程池关闭前等待当前任务完成
- ✅ 数据库连接池在关闭前释放
- ✅ 消息队列消费者在关闭前完成 ack
- ✅ 注册中心服务下线通知
- ✅ 设置合理的超时时间(防止无限等待)
这样配置后,你的 Java 应用可以实现标准的 Kubernetes SIGTERM → 优雅停机 → 超时后 SIGKILL 的完整流程。
版权声明:足球直播
足球直播
足球直播
足球直播
足球直播
中超直播
中超直播
中超直播
中超直播
中超直播
英超直播
英超直播
英超直播
英超直播
英超直播
德甲直播
德甲直播
德甲直播
德甲直播
德甲直播
西甲直播
西甲直播
西甲直播
西甲直播
西甲直播
意甲直播
意甲直播
意甲直播
意甲直播
意甲直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
足球直播
足球直播
足球直播
足球直播
足球直播
中超直播
中超直播
中超直播
中超直播
中超直播
英超直播
英超直播
英超直播
英超直播
英超直播
德甲直播
德甲直播
德甲直播
德甲直播
德甲直播
西甲直播
西甲直播
西甲直播
西甲直播
西甲直播
意甲直播
意甲直播
意甲直播
意甲直播
意甲直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
足球直播
足球直播
足球直播
足球直播
足球直播
中超直播
中超直播
中超直播
中超直播
中超直播
英超直播
英超直播
英超直播
英超直播
英超直播
德甲直播
德甲直播
德甲直播
德甲直播
德甲直播
西甲直播
西甲直播
西甲直播
西甲直播
西甲直播
意甲直播
意甲直播
意甲直播
意甲直播
意甲直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播