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


    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的命令停止服务,不然优雅停止不会生效。


    __EOF__

  • 本文作者: 柳先开
  • 本文链接: https://www.cnblogs.com/liuxiankai/p/16242466.html
  • 关于博主: 评论和私信会在第一时间回复。或者直接私信我。
  • 版权声明: 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
  • 声援博主: 如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。
  • 相关阅读:
    Markdown 常用数学公式符号记录
    Go Context 原理详解
    亿流量大考(2):开发一套高容错分布式系统
    camshift实现目标跟踪
    javascript选择器的封装,只需要写元素名或css类及id都可以选择到元素
    【ARM-0】基本概念
    netty源码系列之-02_EventLoopGroup和EventLoop
    Mapbox 与 Babylon.js 可视化 给车身添加贴图
    【FAQ】应用内支付服务无法拉起支付页面常见原因分析和解决方法
    计算机毕设 机器学习股票大数据量化分析与预测系统 - python 计算机毕设
  • 原文地址:https://www.cnblogs.com/liuxiankai/p/16242466.html