SpringBoot2.3新特性优雅停机详解

SpringBoot2.3新特性优雅停机详解

简介

在以往的项目中,我们在正常停止服务时,往往都是使用kill的方式来停止,这种方式虽然简单,但是可能会导致一些问题,比如程序被强制关闭时,可能会导致正在处理的请求直接中断等问题。SpringBoot2.3中新增了一个优雅停机的功能,可以让我们在停止服务时,更加安全和优雅。

优雅停机的原理

在之前的SpringBoot版本中,当我们使用kill命令关闭程序时,操作系统都是直接向程序发送SIGTERM信号,让程序进行退出。但是在SpringBoot2.3中,程序会在收到SIGTERM信号时,进行优雅停机操作,它的流程如下:

  1. 在收到SIGTERM信号后,程序会停止接收新的请求。
  2. 当所有正在处理的请求处理完毕后,程序会优雅退出。

使用示例

下面是两个使用示例:

示例1:使用默认的优雅停机配置

在SpringBoot2.3中,我们只需要在application.properties配置文件中添加下面的配置,即可使用默认的优雅停机功能:

server.shutdown=graceful

同时,在我们的Java代码中,可以在SpringApplication.run方法中添加下面的内容,来手动触发关闭程序:

@SpringBootApplication
public class Application {

    public static void main(String[] args) {
        SpringApplication application = new SpringApplication(Application.class);
        ConfigurableApplicationContext context = application.run(args);

        // 注册关闭钩子
        context.registerShutdownHook();
    }
}

这样,在关闭程序时,程序会自动触发优雅停机操作。

示例2:自定义优雅停机配置

如果需要自定义优雅停机的配置,我们需要创建一个实现了GracefulShutdown接口的类,然后在application.properties配置文件中添加下面的配置:

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

其中,GracefulShutdown接口有两个方法,分别是shutdown()getPhase()shutdown()方法中是自定义的优雅关闭逻辑,getPhase()方法则是返回一个数值,表示该关闭操作的阶段。

下面是一个示例:

@Configuration
public class GracefulShutdownConfig {

    @Bean
    public GracefulShutdown gracefulShutdown() {
        return new GracefulShutdown();
    }

    private class GracefulShutdown implements GracefulShutdownCallback, GracefulShutdown {
        private final Logger logger = LoggerFactory.getLogger(GracefulShutdown.class);
        private volatile boolean isShuttingDown = false;
        private final AtomicInteger shutdownCount = new AtomicInteger(0);  // 统计关闭请求次数
        private CountDownLatch shutDownLatch = new CountDownLatch(1);

        @Override
        public void shutdown() {
            if (!this.isShuttingDown) {
                this.isShuttingDown = true;
                logger.info("Shutdown is being called......");

                Thread td = new Thread(() -> {
                    // 判断是否还有未完成的请求
                    int loopCount = 0;
                    while (true) {
                        if(Service.getIsFinished()) {
                            break;
                        }else if(shutdownCount.get() == 1) {
                            Service.finish();
                        }else if(loopCount >= 60) {
                            logger.info("Timeout exit because of 60 loops check finished");
                            Service.finish();
                        }else {
                            logger.info("wait for all services finish up......num of task unfinish : {}", Service.getTaskCount() - Service.getFinishCount());
                            try {
                                Thread.sleep(1000L);
                                loopCount += 1;
                            } catch (InterruptedException e) {
                                logger.error("Close sleep exception {}", e.getMessage());
                            }
                        }
                    }

                    // 关闭服务器
                    shutDownLatch.countDown();
                });
                td.setDaemon(false);
                td.start();
            }

            try {
                shutDownLatch.await(30, TimeUnit.SECONDS);
                logger.info("Shutdown is finished......");
            } catch (InterruptedException e) {
                logger.error("Close Timing out Eclipse processes: ", e);
            }

        }

        @Override
        public int getPhase() {
            return Integer.MAX_VALUE;   // 返回一个较大的数字,保证该操作是最后一步执行
        }

        @Override
        public String toString() {
            return this.getClass().getSimpleName();
        }
    }
}

在该示例中,我们定义了一个GracefulShutdownConfig配置类,其中包含一个实现了GracefulShutdown接口的GracefulShutdown内部类。在shutdown()方法中,我们进行了自定义的关闭逻辑,首先判断程序中是否还有未完成的请求,如果有,则等待请求完成,然后在关闭服务器;如果无未完成的请求,则直接关闭服务器。

getPhase()中,我们返回了一个较大的数字,保证该操作是在其他关闭操作完成后,最后一个执行。

总结

SpringBoot2.3中添加了优雅停机的功能,可以让我们在关闭程序时更加安全和优雅。我们可以使用默认的配置,也可以进行自定义配置。在自定义配置时,我们需要创建一个实现了GracefulShutdown接口的类,在其中编写自己的优雅停机逻辑。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:SpringBoot2.3新特性优雅停机详解 - Python技术站

(0)
上一篇 2023年5月15日
下一篇 2023年5月15日

相关文章

  • Spring循环依赖之问题复现详解

    下面我将详细讲解“Spring循环依赖之问题复现详解”的完整攻略,包含两条示例。 Spring循环依赖问题复现详解 什么是Spring循环依赖问题 当两个或更多的bean需要相互依赖时,就会发生Spring的循环依赖问题。当两个bean之间存在依赖时,容器负责解决依赖关系。但是,当存在循环依赖时,容器不能解决这个问题。 如何复现Spring循环依赖问题 下面…

    Java 2023年5月19日
    00
  • Java中类的定义与实例化详解

    Java中的类是面向对象编程的基础,类不仅定义了对象的属性和方法,还可以作为对象的模板来创建具体的实例。 类的定义 Java中,可以通过关键字class来定义一个类,类的定义通常包含以下几个方面: 访问修饰符,可以是public、private、protected或默认不写; 关键字class; 类的名字; 类的属性,包括属性名和属性类型; 类的方法,包括方…

    Java 2023年5月26日
    00
  • php中最简单的字符串匹配算法

    下面是关于“php中最简单的字符串匹配算法”的详细讲解攻略: 简介 字符串匹配算法是一种常见的算法,在实际的开发中非常常见,例如搜索引擎中的搜索功能、字符串替换等。在PHP中,字符串匹配算法通常用于文本处理、爬虫等场景。本文将介绍PHP中最简单的字符串匹配算法——暴力匹配法,以及该算法的核心原理和应用场景。 暴力匹配法 暴力匹配法是最简单粗暴的一种字符串匹配…

    Java 2023年5月19日
    00
  • Java解析Excel文件并把数据存入数据库

    关于如何用Java解析Excel文件并把数据存入数据库,下面提供一份完整的攻略供你参考。 准备工作 在开始操作之前,需要你先准备好以下工具和环境: JDK:Java开发环境。你可以从Oracle官网上下载安装最新版的JDK。 MySQL:数据库系统。你可以根据需要安装在本地或者使用云服务商提供的MySQL服务。 Apache POI:用于操作Excel文件的…

    Java 2023年5月19日
    00
  • Tomcat安装shell脚本的方法步骤

    下面是详细讲解Tomcat安装shell脚本的方法步骤: 1. 确定Tomcat版本和安装路径 首先需要确定需要安装的Tomcat版本和安装路径。可以去Tomcat官方网站下载最新的安装包,解压后确定解压后文件夹的路径。 2. 创建安装脚本 在Linux系统中创建一个新的文本文件,扩展名为“.sh”,例如“install_tomcat.sh”。并使用任意文本…

    Java 2023年5月19日
    00
  • Java开发学习之Bean的生命周期详解

    Java开发学习之Bean的生命周期详解 什么是Bean 在Java中,一个Java类如果被添加了特殊的注解,就可以被称为一个Bean,而这个类的实例就是一个实例化的Bean。 Bean是Java语言中一种特殊的类,是一个组件,含有规范的属性和行为,并且可以通过接口来定义。 Bean的生命周期 在Java中,Bean的生命周期从创建、初始化、使用到销毁,可以…

    Java 2023年5月20日
    00
  • 使用springboot+druid双数据源动态配置操作

    下面是“使用SpringBoot+Druid双数据源动态配置操作”的完整攻略及两条示例。 一、概述 在实际的项目开发中,经常会遇到同时操作多个不同的数据库的情况,比如读写分离、多租户等。使用SpringBoot+Druid双数据源动态配置操作,可以有效地解决这些问题。 二、配置SpringBoot+Druid 1. 引入相关依赖 在 pom.xml 文件中加…

    Java 2023年5月20日
    00
  • java中编码问题的处理方案

    Java中编码问题的处理方案 在Java开发过程中,我们经常会遇到编码问题,这是由于不同的操作系统、编码方式之间的差异导致的。为了避免出现编码问题,我们需要在开发中采取一些处理方案。 1. 统一编码格式 为了保证代码的可移植性,我们应该统一采用UTF-8编码格式,这样就可以避免不同编码格式之间的互相转换和兼容性问题。 在Java中,我们可以通过设置Java虚…

    Java 2023年5月20日
    00
合作推广
合作推广
分享本页
返回顶部