SpringBoot如何优雅关闭(SpringBoot2.3&Spring Boot2.2)

优雅停止&暴力停止

  • 暴力停止:像日常开发过程中,测试区或者本地开发时,我们并不会考虑项目关闭带来的影响,只是想最快速的关掉重启,所以用的最多的就是kill -9进行暴力停止服务;kill -9的结果就是强制关闭,不会等待服务释放资源等操作,这也造成了,服务中很多进程无法正常结束。
  • 优雅停止:何谓优雅停止,就是等待已有的进程结束之后关闭服务,那么如何实现优雅停止SpringBoot服务?

实现优雅停止

SpringBoot要实现优雅停止,分两种情况一个是SpringBoot版本为2.3.0之前,一种是2.3.0及往后的版本。

  • SpringBoot 2.3.0及后续版本

    在SpringBoot的ReleaseNotes中我们可以看到,在2.3.0版本,SpringBoot新特性中有一个叫GraceFul shutdown的字样。

    意思就是,可以通过配置server.shutdown来实现优雅关闭SpriingBoot服务,支持内嵌的Jetty,Reactor,Netty,Undertow服务器,在配置了优雅停止的情况下关闭服务,服务将不会接收后续请求, 并且会等待宽限期,以便完成当前已有请求。

    配置解释:

    1. server.shutdown : graceful : 表示开启优雅停止
    2. spring.lifecycle.timeout-per-shutdown-phase : 60 :表示最大等待的宽限时间,超过这个时间还有请求没结束的话,会强制关闭服务。

    注意:这里需要注意的是,不能使用kill -9的命令停止服务,不然优雅停止的配置不会生效。

  • SpringBoot2.3.0之前的版本

    在上述的ReleaseNotes看到,配置的方式实现优雅停止时2.3.0之后才有的功能,那往前的版本怎么办?自己手动写。

    @Slf4j
    @SpringBootApplication(exclude = DataSourceAutoConfiguration.class)
    public class NginxTestApplication { public static void main(String[] args) {
    SpringApplication.run(NginxTestApplication.class, args);
    } /**
    * 用于接受 shutdown 事件
    */
    @Bean
    public GracefulShutdown gracefulShutdown() {
    return new GracefulShutdown();
    } @Bean
    public ServletWebServerFactory servletContainer() {
    TomcatServletWebServerFactory tomcat = new TomcatServletWebServerFactory();
    tomcat.addConnectorCustomizers(gracefulShutdown());
    return tomcat;
    } /**
    * 优雅关闭 Spring Boot
    */
    private static class GracefulShutdown implements TomcatConnectorCustomizer, ApplicationListener<ContextClosedEvent> {
    private volatile Connector connector; //获取tomcat的connector
    @Override
    public void customize(Connector connector) {
    this.connector = connector;
    } //监听事件
    @Override
    public void onApplicationEvent(ContextClosedEvent contextClosedEvent) {
    //拒绝停机操作的后续请求
    this.connector.pause();
    log.info("停止Tomcat connector, 拒绝接收后续请求");
    //获取对应线程池并做对应类型判断,true则开始优雅关闭
    Executor executor = this.connector.getProtocolHandler().getExecutor();
    if (executor instanceof ThreadPoolExecutor) {
    try {
    ThreadPoolExecutor threadPoolExecutor = (ThreadPoolExecutor) executor;
    //开始关闭线程池
    threadPoolExecutor.shutdown();
    log.info("开始关闭线程池");
    //最大宽限时间
    int waitTime = 30;
    //若线程池中有未完成事件,等待完成后关闭,若超过最大宽限时间未完成,强制关闭;
    //若没有未完成事件,直接关闭
    if (!threadPoolExecutor.awaitTermination(waitTime, TimeUnit.SECONDS)) {
    log.info("Tomcat线程池无法在"+waitTime+"s 内优雅关闭. 强制结束");
    }
    } catch (InterruptedException ex) {
    Thread.currentThread().interrupt();
    }
    }
    }
    } }

    在启动类中加上这些东西就行了,写了很多注释,就不详细解释了。

    注意:这里同样需要注意的是,不能使用kill -9的命令停止服务,不然优雅停止不会生效。

SpringBoot如何优雅关闭(SpringBoot2.3&Spring Boot2.2)的更多相关文章

  1. 如何在 Spring Boot 优雅关闭加入一些自定义机制

    个人创作公约:本人声明创作的所有文章皆为自己原创,如果有参考任何文章的地方,会标注出来,如果有疏漏,欢迎大家批判.如果大家发现网上有抄袭本文章的,欢迎举报,并且积极向这个 github 仓库 提交 i ...

  2. 如何优雅关闭 Spring Boot 应用

    ## 前言 随着线上应用逐步采用 SpringBoot 构建,SpringBoot应用实例越来多,当线上某个应用需要升级部署时,常常简单粗暴地使用 kill 命令,这种停止应用的方式会让应用将所有处理 ...

  3. 图书-技术-SpringBoot:《Spring Boot2 + Thymeleaf 企业应用实战》

    ylbtech-图书-技术-SpringBoot:<Spring Boot2 + Thymeleaf 企业应用实战> <Spring Boot 2+Thymeleaf企业应用实战&g ...

  4. SpringBoot之整合Quartz调度框架-基于Spring Boot2.0.2版本

    1.项目基础 项目是基于Spring Boot2.x版本的 2.添加依赖 <!-- quartz依赖 --> <dependency> <groupId>org.s ...

  5. spring boot2 kafka

    一.软件版本 1.linux:centos6 2.zookeeper:zookeeper-3.4.1 3.kafka:kafka_2.12-2.2.0 4.jdk:1.8 5.instelliJ Id ...

  6. 【spring cloud】spring cloud2.X spring boot2.0.4调用feign配置Hystrix Dashboard 和 集成Turbine 【解决:Hystrix仪表盘Unable to connect to Command Metric Stream】【解决:Hystrix仪表盘Loading...】

    环境: <java.version>1.8</java.version><spring-boot.version>2.0.4.RELEASE</spring- ...

  7. 深入分析Spring Boot2,解决 java.lang.ArrayStoreException异常

    将某个项目从Spring Boot1升级Spring Boot2之后出现如下报错,查了很多不同的解决方法都没有解决: Spring boot2项目启动时遇到了异常: java.lang.ArraySt ...

  8. Spring Boot2.0 整合 Kafka

    Kafka 概述 Apache Kafka 是一个分布式流处理平台,用于构建实时的数据管道和流式的应用.它可以让你发布和订阅流式的记录,可以储存流式的记录,并且有较好的容错性,可以在流式记录产生时就进 ...

  9. Spring-IOC 在非 web 环境下优雅关闭容器

    当我们设计一个程序时,依赖了Spring容器,然而并不需要spring的web环境时(Spring web环境已经提供了优雅关闭),即程序启动只需要启动Spring ApplicationContex ...

随机推荐

  1. Zookeeper Watcher 机制 -- 数据变更通知 ?

    Zookeeper 允许客户端向服务端的某个 Znode 注册一个 Watcher 监听,当服务 端的一些指定事件触发了这个 Watcher,服务端会向指定客户端发送一个事件通 知来实现分布式的通知功 ...

  2. 学习Cobbler(二)

    Server端: 第一步,启动Cobbler服务 第二步,进行Cobbler错误检查,执行cobbler check命令 第三步,进行配置同步,执行cobbler sync命令 第四步,复制相关启动文 ...

  3. 学习 Haproxy (三)

    HAProxy安装 # wget http://www.haproxy.org/download/1.4/src/haproxy-1.4.24.tar.gz # tar xf haproxy-1.4. ...

  4. 二、cadence焊盘与封装制作操作步骤详细说明

    一.焊盘制作 1.打开Pad Designer软件,新建文件--设置保存路径和焊盘名称(规范命名) 2.Parameters--设置单位--过孔类型--是否镀金 3.Layers--single la ...

  5. JS练习实例--编写经典小游戏俄罗斯方块

    最近在学习JavaScript,想编一些实例练练手,之前编了个贪吃蛇,但是实现时没有注意使用面向对象的思想,实现起来也比较简单所以就不总结了,今天就总结下俄罗斯方块小游戏的思路和实现吧(需要下载代码也 ...

  6. SVG中的坐标系统和坐标变换

    视野和世界 2D绘图中很多人会有一个误区,就是我绘图的区域是一个矩形区域.无论新建一个画布还是创建了一个容器,心里都想象里面有一个矩形区域.其实,在SVG当中,矩形区域只是视野,是我们看到的部分.实际 ...

  7. 体温登记app开发流程

    关于体温app,比较难的是获取定位信息,剩下的就是增删改查. 设计思路:首先布局一个添加页面,给每个元件添加id,之后在获取地点的EditText获取位置信息,在添加两个布局文件,体现在一个页面里用来 ...

  8. 自定义View的onDraw 函数不执行

    解决办法:    在自定义的View 的构造方法中添加一句话:   this.setWillNotDraw(false);解释:那么加这条语句的作用是什么?先看API:        If this ...

  9. 类其中的变量为final时的用法

    类其中的变量为final时的用法:   类当中final变量没有初始缺省值,必须在构造函数中赋值或直接当时赋值.否则报错. public class Test {     final int i;   ...

  10. ServletContext介绍和用法总结

    ServletContext介绍和用法总结 学习总结 一.ServletContext 介绍 1. 概念 2. 作用 3. 获取 3.1 在实现类中获取 3.2 在 Spring 容器中获取 二.Se ...