---
### **1. JVM 的信号处理与 Spring 的联动**
#### **(1)JVM 的响应**
• **SIGTERM 信号的作用**:`kill -15` 是操作系统通知进程终止的“软终止”信号。JVM 接收到此信号后,会启动 **Shutdown Hook** 机制,依次执行所有注册的关闭钩子(如 Spring 的钩子)。
• **强制终止与优雅终止的区别**:`kill -9`(SIGKILL)会直接终止进程,不触发任何钩子;而 `kill -15` 允许 JVM 执行清理逻辑。
#### **(2)Spring 的注册与触发**
• **Spring 的 Shutdown Hook**:Spring 在启动时(通过 `AbstractApplicationContext`)会向 JVM 注册一个 Shutdown Hook。当 JVM 收到 `SIGTERM` 时,该 Hook 会调用 Spring 的 `doClose()` 方法,触发以下操作:
1. 发布 `ContextClosedEvent` 事件,通知监听器容器即将关闭。
2. 销毁所有单例 Bean,依次执行 `@PreDestroy` 方法、`DisposableBean#destroy()` 接口方法、自定义销毁方法(如 `destroy-method`)。
3. 关闭内嵌的 Web 服务器(如 Tomcat),停止接收新请求,并等待已有请求处理完成。
---
### **2. Spring 优雅关闭的核心流程**
#### **(1)Bean 销毁与资源释放**
• **`@PreDestroy` 注解**:标记在 Bean 方法上,Spring 会在销毁前调用该方法释放资源(如关闭数据库连接)。
• **`DisposableBean` 接口**:实现该接口的 Bean 需定义 `destroy()` 方法,用于自定义清理逻辑。
• **自定义销毁方法**:通过 XML 或 Java 配置的 `destroy-method` 属性指定。
#### **(2)Web 服务器的优雅停机**
• **Tomcat 的关闭逻辑**:Spring 会关闭 Tomcat 的连接器(停止接受新请求),并轮询检查所有活跃请求是否完成。若未完成,则等待至超时(默认 30 秒)后强制终止。
• **配置优化**:在 Spring Boot 2.3+ 中,可通过 `server.shutdown=graceful` 和 `spring.lifecycle.timeout-per-shutdown-phase=30s` 调整等待时间。
#### **(3)微服务场景的扩展**
• **注册中心注销**:在 Spring Cloud 中,服务会先从注册中心(如 Nacos、Eureka)下线,避免其他服务继续调用已关闭实例。
• **客户端缓存问题**:即使服务已注销,客户端可能因本地缓存(如 Ribbon 的 30 秒缓存)继续请求旧实例地址,需结合服务发现机制优化等待时间。
---
### **3. 验证与异常处理**
#### **(1)验证流程**
• **日志观察**:执行 `kill -15` 后,Spring 会输出以下日志:
```log
Closing org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext
Unregistering JMX-exposed beans on shutdown
ShutdownHook executed
```
• **测试案例**:对比 `kill -15` 与 `kill -9`,前者会触发 Bean 销毁和资源释放,后者直接终止进程且无清理日志。
#### **(2)异常处理**
• **超时强制终止**:若关闭阶段超时(如请求未处理完),Spring 会记录警告并终止 JVM。
• **死锁与阻塞**:若 Shutdown Hook 因死锁卡住,需结合运维监控(如 Kubernetes 的 `terminationGracePeriodSeconds`)设置强制终止阈值。
---
### **4. 最佳实践**
1. **优先使用 `kill -15`**:避免 `kill -9` 导致数据不一致或资源泄漏。
2. **配置超时时间**:根据业务场景调整 `spring.lifecycle.timeout-per-shutdown-phase`,平衡关闭速度与请求完整性。
3. **结合容器化部署**:在 Kubernetes 中配置 `preStop Hook`,先注销服务再等待缓存过期,最后发送 `SIGTERM`。
4. **监控关闭事件**:通过 `ApplicationListener<ContextClosedEvent>` 监听关闭事件,补充自定义清理逻辑。
---
### **总结**
JVM 收到 `kill -15` 信号后,会触发 Spring 的优雅关闭流程,包括 Bean 销毁、资源释放和 Web 服务器停机。这一机制依赖 Spring 注册的 Shutdown Hook 和生命周期管理,确保服务终止时数据安全和系统稳定。
0 回复
- 请尽量让自己的回复能够对别人有帮助
- 支持 Markdown 格式, **粗体**、~~删除线~~、
`单行代码`
- 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
- 图片支持拖拽、截图粘贴等方式上传