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日

相关文章

  • SpringBoot使用freemarker导出word文件方法详解

    SpringBoot使用freemarker导出word文件方法详解 在SpringBoot框架中,使用freemarker库可以轻松地将数据和模板结合起来生成各种文件类型。其中,导出word文件是一个常见的需求,本文将详细介绍SpringBoot如何使用freemarker导出word文件。 步骤一:添加依赖 首先,在pom.xml文件中添加freemar…

    Java 2023年5月20日
    00
  • jenkins+Maven从SVN上构建项目的方法

    下面我会给你详细讲解使用Jenkins和Maven从SVN上构建项目的方法,包含以下步骤: 安装Jenkins 安装Maven 构建Jenkins的SVN插件 创建Jenkins的SVN配置 创建Jenkins的Maven构建配置 创建Jenkins的构建任务 下面我们将逐一介绍这些步骤的具体内容。 1. 安装Jenkins 如果你还没有安装Jenkins,…

    Java 2023年5月20日
    00
  • 使用smartupload组件实现jsp+jdbc上传下载文件实例解析

    使用smartupload组件实现JSP+JDBC上传下载文件,需要经过以下步骤: 下载SmartUpload组件 从官方网站 http://smartupload.io/ 下载最新版本的SmartUpload组件(smartupload.jar),并将其添加到项目的classpath中。 配置Web.xml 在Web.xml中配置SmartUpload的处…

    Java 2023年6月15日
    00
  • Java对象的创建过程是什么?

    Java对象的创建过程是Java程序中非常基础、也非常重要的一部分。在Java编程中开发者需要清楚理解Java对象创建的整个流程,本文将为读者详细讲解Java对象的创建过程。 Java对象的创建过程 在Java编程中,创建一个Java对象涉及到了三个步骤: 1、类的加载与加载机制 类的加载与加载机制是Java程序启动时的第一步,Java类需要在Java虚拟机…

    Java 2023年5月11日
    00
  • Jsp中如何让图片在div中居中

    让图片在 DIV 中居中可以使用 CSS 实现。下面是操作步骤和两个示例说明: 步骤 在 JSP 文件中,使用 <div> 标签定义包含图片的容器。 给此 div 标签设置宽度、高度、背景等样式,使其成为一个完整的盒子。 在 div 中嵌套 img 标签,定义图片的地址和大小。 在 CSS 样式文件中,使用 text-align: center;…

    Java 2023年6月15日
    00
  • java 对象数组排序

    Java对象数组排序攻略 在Java中,有时会使用对象数组来存储多个对象,对这些对象按照某个属性进行排序是很常见的需求。本攻略将介绍如何对Java对象数组进行排序。 一、对象数组排序的准备 首先,我们需要定义一个Java类来表示我们要排序的对象。这个Java类至少需要包含一个我们希望排序的属性,并实现Comparable接口。该接口有一个compareTo方…

    Java 2023年5月26日
    00
  • spring boot starter actuator(健康监控)配置和使用教程

    Spring Boot Starter Actuator配置和使用教程 Spring Boot Starter Actuator是Spring Boot提供的一个用于监控和管理应用程序的模块。它提供了许多有用的端点,例如/health、/info、/metrics等,可以帮助我们监控应用程序的健康状况、性能指标等。在本文中,我们将详细讲解Spring Boo…

    Java 2023年5月15日
    00
  • 数据库CURD必备搭档mybatis plus详解

    数据库CURD必备搭档mybatis plus详解 什么是MyBatis Plus MyBatis Plus是一个基于MyBatis的增强工具,简化了MyBatis的操作,减少了开发人员的工作量,让开发人员能够更加专注于业务逻辑的实现。 MyBatis Plus的常用功能 快速Mapper接口的开发 自动分页 自动注入公共字段 代码生成器 快速开发Mappe…

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