网站设计时间,网上营销新观察网,专业网站建设网站研发深圳公司,做网页制作的价格#x1f3f7;️个人主页#xff1a;牵着猫散步的鼠鼠 #x1f3f7;️系列专栏#xff1a;Java全栈-专栏 #x1f3f7;️个人学习笔记#xff0c;若有缺误#xff0c;欢迎评论区指正 目录
前言
优雅停机是什么
SpringBoot如何实现优雅停机
合理杀死进程
法一… ️个人主页牵着猫散步的鼠鼠 ️系列专栏Java全栈-专栏 ️个人学习笔记若有缺误欢迎评论区指正 目录
前言
优雅停机是什么
SpringBoot如何实现优雅停机
合理杀死进程
法一配置设置SpringBoot优雅停机
法二配置Tomcat 容器优雅停机
设置Tomcat 容器关闭代码
设置 Tomcat 自动装配
总结 前言
在服务器环境中,确保应用程序能够平滑关闭并处理完所有现有请求是一个重要的需求。Spring Boot 为我们提供了优雅退出的功能,使应用程序能够在关闭时正常处理完所有当前请求,避免请求被中断导致数据丢失或不一致等问题。本文将全面介绍如何在 Spring Boot 应用程序中实现优雅退出。
优雅停机是什么
优雅停机Graceful Shutdown 是指在服务器需要关闭或重启时能够先处理完当前正在进行的请求然后再停止服务的操作。
优雅停机的实现步骤主要分为以下几步
停止接收新的请求首先系统会停止接受新的请求这样就不会有新的任务被添加到任务队列中。处理当前请求系统会继续处理当前已经在处理中的请求确保这些请求能够正常完成。这通常涉及到等待正在执行的任务完成如处理HTTP请求、数据库操作等。释放资源在请求处理完成后系统会释放所有已分配的资源如关闭数据库连接、断开网络连接等。关闭服务最后当所有请求都处理完毕且资源都已释放后系统会安全地关闭服务。
SpringBoot如何实现优雅停机
优雅停机的实现步骤分为以下两步
使用合理的 kill 命令给 Spring Boot 项目发送优雅停机指令。开启 Spring Boot 优雅停机/自定义 Spring Boot 优雅停机的实现。
合理杀死进程
在 Linux 中 kill 杀死进程的常用命令有以下这些
kill -2 pid向指定 pid 发送 SIGINT 中断信号等同于 ctrlc。也就说不仅当前进程会收到该信号而且它的子进程也会收到终止的命令。kill -9 pid向指定 pid 发送 SIGKILL 立即终止信号。程序不能捕获该信号最粗暴最快速结束程序的方法。kill -15 pid向指定 pid 发送 SIGTERM 终止信号。信号会被当前进程接收到但它的子进程不会收到如果当前进程被 kill 掉它的的子进程的父进程将变成 init 进程 (init 进程是那个 pid 为 1 的进程)。kill pid等同于 kill 15 pid。
因此在以上命令中我们不能使用“kill -9”来杀死进程使用“kill”杀死进程即可。
法一配置设置SpringBoot优雅停机
在 Spring Boot 2.3.0 之后可以通过配置设置开启 Spring Boot 的优雅停机功能如下所示
# 开启优雅停机默认值immediate 为立即关闭
server.shutdowngraceful# 设置缓冲期最大等待时间默认30秒
spring.lifecycle.timeout-per-shutdown-phase60s此时应用在关闭时Web 服务器将不再接受新请求并等待正在进行的请求完成的缓冲时间。
然而如果是 Spring Boot 2.3.0 之前就需要自行扩展线程池来实现优雅停机了。它的核心实现实现是在系统关闭时会调用 ShutdownHook然后在 ShutdownHook 中阻塞 Web 容器的线程池直到所有请求都处理完毕再关闭程序这样就实现自定义优雅线下了。
但是不同的 Web 容器Tomcat、Jetty、Undertow有不同的自定义优雅停机的方法以 Tomcat 为例它的自定义优雅停机实现如下。
法二配置Tomcat 容器优雅停机
设置Tomcat 容器关闭代码
实现 TomcatConnectorCustomizer 接口,用于在应用关闭时暂停 Tomcat 连接器:
public class TomcatGracefulShutdown implements TomcatConnectorCustomizer, ApplicationListenerContextClosedEvent {private volatile Connector connector;public void customize(Connector connector) {this.connector connector;}public void onApplicationEvent(ContextClosedEvent contextClosedEvent) {this.connector.pause();Executor executor this.connector.getProtocolHandler().getExecutor();if (executor instanceof ThreadPoolExecutor) {try {log.info(Start to shutdown tomcat thread pool);ThreadPoolExecutor threadPoolExecutor (ThreadPoolExecutor) executor;threadPoolExecutor.shutdown();if (!threadPoolExecutor.awaitTermination(20, TimeUnit.SECONDS)) {log.warn(Tomcat thread pool did not shutdown gracefully within 20 seconds. );}} catch (InterruptedException e) {log.warn(Fail to shut down tomcat thread pool , e);}}}
}设置 Tomcat 自动装配
在配置类中声明该 Bean 并将其注册为 Tomcat 的 ConnectorCustomizer:
Configuration
ConditionalOnClass({Servlet.class, Tomcat.class})
public static class TomcatConfiguration {Beanpublic TomcatGracefulShutdown tomcatGracefulShutdown() {return new TomcatGracefulShutdown();}Beanpublic EmbeddedServletContainerFactory tomcatEmbeddedServletContainerFactory(TomcatGracefulShutdown gracefulShutdown) {TomcatEmbeddedServletContainerFactory tomcatFactory new TomcatEmbeddedServletContainerFactory();tomcatFactory.addConnectorCustomizers(gracefulShutdown);return tomcatFactory;}
}总结
实现应用程序的优雅退出对于确保服务的可靠性和数据一致性至关重要。Spring Boot 从 2.3.0 版本开始提供了开箱即用的优雅退出支持,低于该版本则需要手动扩展实现。无论使用哪种方式,都应该遵循上述最佳实践,以确保应用程序能够安全、高效地关闭。同时,对于不同的 Web 容器,优雅退出的具体实现细节也会有所差异,需要合理配置。