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. Statement 和 PreparedStatement 有什么区别?哪个性 能更好?

    与 Statement 相比,①PreparedStatement 接口代表预编译的语句,它主要的优 势在于可以减少 SQL 的编译错误并增加 SQL 的安全性(减少 SQL 注射攻击的可 能性):② ...

  2. memcached 如何实现冗余机制?

    不实现!我们对这个问题感到很惊讶.Memcached 应该是应用的缓存层.它的设 计本身就不带有任何冗余机制.如果一个 memcached 节点失去了所有数据,您 应该可以从数据源(比如数据库)再次获 ...

  3. session与cookie的区别? 如果客户端禁止 cookie session 还能用吗?

    一.session与cookie的区别 session:Session 是存放在服务器端的,类似于Session结构来存放用户数据,当浏览器 第一次发送请求时,服务器自动生成了一个Session和一个 ...

  4. 在多线程环境下,SimpleDateFormat 是线程安全的吗?

    不是,非常不幸,DateFormat 的所有实现,包括 SimpleDateFormat 都不是 线程安全的,因此你不应该在多线程序中使用,除非是在对外线程安全的环境中 使用,如 将 SimpleDa ...

  5. SVN回滚步骤

  6. 订单突破10000+,仅花1小时,APPx独家深入剖析背后的秘密!

    拼多多:成立三年,获客三亿,月订单成交额达到恐怖的400亿,成功上市! 糕妈优选:营销活动推送1小时,订单超过10000+,商品成功刷屏朋友圈! 寻慢:一场活动净增7000+粉丝,付款转化率高达71% ...

  7. HTML5 Performance

    简介 performance是html5的新特性之一,通过它,页面的开发者们可以非常精确的统计到自己页面的表现情况,从而有针对性的进行优化,提升用户体验. 下面是小姐姐对performance相关AP ...

  8. javaweb图书管理系统之不同用户跳转不同页面

    关于分级自测题,我们知道该系统一共分为两个角色,一个是读者,一个是管理员,我们需要根据不同用户去到不同的页面,所以我们需要写一个登陆界面. 本文先写这个功能的实现,该功能主要在servlet里面实现. ...

  9. IDEA 生成返回值对象快捷键Ctrl+Alt+V失效

    在IDEA上运用快捷键返回对象(Ctrl+Alt+V)的时候一直无效,找了很久的问题,发现是有快捷键冲突,发现QQ音乐快捷键与IDEA冲突了,把那处改掉或者关闭即可. 所以边敲代码边听音乐也要注意一下

  10. Spark入门之idea编写Scala脚本

    一.安装Scala插件 1.File->Settings 2.Plugins->Msrketplace->搜索Scala并安装 (或者自己下载合适的scala版本,教程:自己给ide ...