2024-12-16  阅读(7)
版权声明:本文为博主付费文章,严禁任何形式的转载和摘抄,维权必究。 本文链接:https://www.skjava.com/mianshi/baodian/detail/1112019606

回答

Spring Boot 应用的优雅停机是为了应用在关闭时,能够合理地释放资源,完成一些必要的清理工作,并保证不影响正在处理的请求。

要实现 Spring Boot 的优雅停机,可以有如下几种方式:

  • 启用 Spring Boot 的 Graceful Shutdown 功能

在 Spring Boot 2.3+ 中,它内置了优雅停机支持只需在 application.properties 启用即可,参数配置:server.shutdown=graceful

  • 定义 @PreDestroy 或实现 DisposableBean 接口

如果我们要执行一些清理逻辑,比如关闭数据库连接池,释放缓存等等,则可以使用 @PreDestroy 或者实现 DisposableBean 接口。

  • 使用 ApplicationListener 监听上下文关闭事件

我们也可以使用 ApplicationListener 来监听 ContextClosedEvent 事件来实现我们的清理逻辑。

Spring Boot 优雅停机方式

1、启用 Spring Boot 优雅停机

Spring Boot 2.3+ 引入了对 graceful shutdown 的直接支持。我们只需要在配置文件中直接启用即可:

server.shutdown=graceful
spring.lifecycle.timeout-per-shutdown-phase=45s

  • server.shutdown=graceful :就是在告诉容器,在关闭时不要立刻终止线程,而应该是等待所有正在处理的请求完成后再关闭。它的底层实现依赖于 Servlet 容器(如 Tomcat、Jetty)的 Lifecycle 支持。
  • spring.lifecycle.timeout-per-shutdown-phase=30s:设置每个生命周期阶段的超时时间,默认是 30 秒。在这 30 秒内,如果线程执行完毕就会被强制终止。

2、@PreDestroy 和 DisposableBean

在 Spring 中,@PreDestroyDisposableBean 都是用来管理 Bean 生命周期中销毁阶段的机制。

@PreDestroy

@PreDestroy 是 Java 中 JSR-250 规范的注解,它用于标记 Bean 销毁之前需要执行的方法。被它标记的的方法会在容器销毁该 Bean 时调用。

所以,利用它我们可以实现一些资源清理的工作。

@Component
public class DatabaseConnectionPool {

    @PreDestroy
    public void close() {
        System.out.println("关闭数据库连接...");
    }
}

DisposableBean 接口

实现 DisposableBean 接口的 destroy() 就可以了:

@Component
public class DatabaseConnectionPool implements DisposableBean {
    @Override
    public void destroy() throws Exception {
        System.out.println("关闭数据库连接...");
    }
}

对于 @PreDestroyDisposableBean,Spring 会在 AbstractApplicationContextdoClose() 中,会依次调用所有@PreDestroy 标记的方法和实现 DisposableBean 接口的类。

3、使用 ApplicationListener 监听上下文关闭事件

当应用程序关闭时,Spring 会触发 ContextClosedEvent 事件,所以我们只需要监听这个事件就可以自定义我们的关闭逻辑了。

@Component
public class GracefulShutdownListener implements ApplicationListener<ContextClosedEvent> {
    @Override
    public void onApplicationEvent(ContextClosedEvent event) {
        // 添加关闭资源的逻辑
    }
}

SpringBoot应用的优雅停机如何触发

目前有两种主流方式来触发 Spring Boot 的优雅停机:

  1. kill -SIGTERM PID
  2. shutdown 端点

kill -SIGTERM PID