一文带你掌握springBoot如何做到优雅停机的
目录
- 1. 优雅停机的核心目标
- 2. 基于内嵌服务器的优雅停机配置
- 2.1 启用优雅停机
- 2.2 不同服务器的行为
- 2.3 验证停机流程
- 3. 自定义停机逻辑扩展
- 3.1 监听停机事件
- 3.2 使用 @PreDestroy 注解
- 4. 集成 Kubernetes 的优雅停机
- 4.1 配置 PreStop Hook
- 4.2 配合就绪探针
- 5. 常见问题与解决方案
- 6. 验证优雅停机效果
- 总结
在分布式系统中,服务的优雅停机(Graceful Shutdown)是确保业务连续性的重要机制。Spring Boot 通过 内嵌服务器支持 和 生命周期管理 实现了这一功能,以下是具体实现方式和配置细节:
1. 优雅停机的核心目标
- 停止接收新请求:关闭监听端口,不再接受新连接。
- 等待处理中的请求完成:允许正在执行的请求继续处理直至超时。
- 释放资源:关闭数据库连接池、线程池等资源。
- 避免数据不一致:确保事务完整性,防止中途中断。
2. 基于内嵌服务器的优雅停机配置
Spring Boot 从 2.3 版本 开始,为 Tomcat、Jetty、Undertow 等内嵌服务器内置了优雅停机支持。
2.1 启用优雅停机
在 application.properties
或 application.yml
中配置:
server: shutdown: graceful # 启用优雅停机模式 spring: lifecycle: timeout-per-shutdown-phase: 30s # 等待请求完成的超时时间(默认30秒)
2.2 不同服务器的行为
服务器 | 优雅停机行为 |
---|---|
Tomcat | 停止接收新请求,等待处理中的请求完成,超时后强制关闭。 |
Jetty | 停止接收新连接,等待活跃请求完成。 |
Undertow | 关闭监听端口,等待活跃请求完成。 |
2.3 验证停机流程
1.发送停机信号:
通过 SIGTERM
信号(Kill 命令)或 Actuator 端点关编程闭应用。
使用 Actuator 端点需要添加依赖和配置:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency>
management: endpoint: shutdown: enabled: true endpoints: web: exposure: include: shutdown
发送 POST 请求关闭应用:
curl -X POST http://localhost:8080/actuator/shutdown
2.观察日志:
2023-10-05 14:20:00 INFO o.s.b.w.e.tomcat.www.devze.comGracefulShutdown : Commencing graceful shutdown. Waiting for active requests to complete
2023-10-05 14:20:30 INFO o.s.b.w.e.tomcat.GracefulShutdown : Graceful shutdown complete
3. 自定义停机逻辑扩展
3.1 监听停机事件
通过实现 ApplicationListener<ContextClosedEvent>
监听上下文关闭事件:
@Component public class GracefulShutdownListener implements ApplicationListener<ContextClosedEvent> { @Override public void onApplicationEvent(ContextClosedEvent event) { //dubbo关闭 DubboBootstrap.getInstanandroidce().stop(); // 执行自定义清理逻辑(如关闭线程池、释放资源) ExecutorService executor = event.getApplicatphpionContext().getBean(ExecutorService.class); executor.shutdown(); try { if (!executor.awaitTermination(30, TimeUnit.SECONDS)) { executor.shutdownNow(); } } catch (InterruptedException e) { Thread.currentThread().interrupt(); } } }
3.2 使用 @PreDestroy 注解
在 Bean 销毁前执行清理逻辑:
@Service public class DatabaseService { @PreDestroy public void cleanup() { // 关闭数据库连接 DataSource dataSource = ...; dataSource.close(); } }
4. 集成 Kubernetes 的优雅停机
在 Kubernetes 中,结合 Pod 生命周期钩子 实现优雅停机:
4.1 配置 PreStop Hook
在 Deployment 配置中添加 preStop
钩子,延迟终止进程:
spec: template: spec: coandroidntainers: - name: app lifecycle: preStop: exec: command: ["sh", "-c", "sleep 30"] # 等待30秒后发送SIGTERM terminationGracePeriodSeconds: 60 # 总宽限期(包括preStop)
4.2 配合就绪探针
在停机前标记服务不可用:
readinessProbe: httpGet: path: /actuator/health/readiness port: 8080
5. 常见问题与解决方案
问题 | 解决方案 |
---|---|
停机超时后仍有未完成请求 | 调整 spring.lifecycle.timeout-per-shutdown-phase 延长等待时间。 |
线程池任务未执行完 | 自定义 ExecutorService 并在停机时调用 shutdown() 和 awaitTermination()。 |
数据库连接未关闭 | 通过 @PreDestroy 或 DisposableBean 显式关闭连接池。 |
Kubernetes 强制终止 Pod | 确保 terminationGracePeriodSeconds 大于优雅停机超时时间。 |
6. 验证优雅停机效果
1.发送长耗时请求:
curl http://localhost:8080/long-task
2.触发停机:
curl -X POST http://localhost:8080/actuator/shutdown
3.观察结果:
- 新请求返回
503 Service Unavailable
。 - 正在处理的请求继续执行直至完成或超时。
总结
通过 内嵌服务器配置、生命周期钩子 和 Kubernetes 集成,Spring Boot 实现了开箱即用的优雅停机功能。关键配置包括:
- 启用 server.shutdown=graceful。
- 设置合理的超时时间。
- 结合 Actuator 端点或 Kubernetes 生命周期管理。
到此这篇关于一文带你掌握springBoot如何做到优雅停机的的文章就介绍到这了,更多相关springBoot停机内容请搜索编程客栈(www.devze.com)以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程客栈(www.devze.com)!
精彩评论