开发者

一文带你掌握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.propertiesapplication.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)!

        0

        上一篇:

        下一篇:

        精彩评论

        暂无评论...
        验证码 换一张
        取 消

        最新开发

        开发排行榜