资讯专栏INFORMATION COLUMN

SpringBoot停服实践

IT那活儿 / 2270人阅读
SpringBoot停服实践
[
一、介绍
]


当外部流量请求到服务端接口执行业务逻辑的时候,若服务端此时执行关机(kill),springboot 默认情况会直接关闭容器(tomcat等),导致此业务逻辑执行失败。在一些业务场景下会出现数据不一致的情况,事务逻辑不会回滚。


在最新的springboot 2.3版本已内置此功能,不需要再自行扩展容器线程池来处理,目前springboot嵌入式支持的web服务器(Jetty、ReactorNetty、Tomcat和Undertow)以及反应式和基于Servlet的web应用程序都支持优雅停机功能。


此处支持的shutdown行为,我们看下源码枚举如下:

publicenumShutdown{

/**

*优雅停机(限期停机)

*/

GRACEFUL,


/**

*立即停机

*/

IMMEDIATE;


}

[
二、使用方式

]



在application.properties中添加以下配置

当server.shutdown=graceful启用后,在web容器关闭时,web服务器将不再接收新请求,并将在缓冲期内等待活动请求完成。缓冲期timeout-per-shutdown-phase配置:默认时间为30S,意味着最大等待30S,超时后无论线程任务是否执行完毕都会停机处理,需要根据项目实际需要合理设置。


以上配置完毕,重新发布以后,服务端就支持优雅停服了。

[
三、触发优雅停服
]

1、对进程PID执行kill-2 而不是kill-9

  kill-9,暴力美学强制杀死进程,不会执行ShutdownHook;但是kill-2相当于快捷键Ctrl+ C会触发Java的ShutdownHook事件处理,进行优雅停机或者一些后置处理。可参考以下源码:

@Override

publicvoidregisterShutdownHook(){

if(this.shutdownHook== null){

 //No shutdown hook registered yet.

 this.shutdownHook= newThread(SHUTDOWN_HOOK_THREAD_NAME) {

  @Override

  publicvoidrun(){

   synchronized(startupShutdownMonitor) {

    doClose();

   }

  }

 };

 Runtime.getRuntime().addShutdownHook(this.shutdownHook);

}

}

2、通过actuator端点实现优雅停机

前提为项目已加入actuator依赖,以及application.properties加入相关配置如图


此时,POST请求/actuator/shutdown即可执行优雅关机。


源码解析如下:

@Endpoint(id= "shutdown",enableByDefault = false)

publicclassShutdownEndpointimplementsApplicationContextAware{


@WriteOperation

publicMap shutdown(){

Threadthread = newThread(this::performShutdown);

thread.setContextClassLoader(getClass().getClassLoader());

thread.start();

}


privatevoidperformShutdown(){

try{

 Thread.sleep(500L);

}

catch(InterruptedException ex) {

 Thread.currentThread().interrupt();

}


//此处close逻辑和上边shutdownhook的处理一样

this.context.close();

}

}

[
四、例子
]

我们通过一个demo来验证下是否实现了优雅停服,下面是一个http测试接口,请求后返回一个json串。


@GetMapping("/test")
publicObject test(){
   List test = new ArrayList<>();
 
for(inti = 0; i < 5; i++) {
       String s = "test" +i;
       System.out.println(s);
       test.add(s);
     
try{
           Thread.sleep(1000);
       }
catch(InterruptedException e) {
           e.printStackTrace();
      }
   }
   return test;
}


启动项目,正常访问结果如下:


先看下未配置优雅停服前,在访问接口过程中停机的结果。使用Ctrl+ C模拟在请求执行过程中停机,此时请求中断,后端日志抛出异常。


配置好优雅停服后,再模拟上述情况。由下图可以看到服务停止后,停服前的请求能正常返回,日志中也未抛出异常。

[
五、不同springboot嵌入式web容器优雅停机行为区别
]

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/130099.html

相关文章

  • 趣米云:停服运营公告,请大家及时备份数据,请大家申请退款

    摘要:趣米云怎么样趣米云是一家今年三月份新开的国人商家,就在此前还声称过了动荡期,运营已经稳定。但是,趣米云商家突然发布了公告,决定停服停运的公告。趣米云怎么样?趣米云是一家今年三月份新开的国人商家,就在此前还声称过了动荡期,运营已经稳定。但是,趣米云商家突然发布了公告,决定停服停运的公告。就在不久前,商家开启国庆优惠活动,还是原来的套餐,从30每月降到了26每月,估计低价也难得获取到新的客户,所...

    stefanieliang 评论0 收藏0
  • 立根铸魂,麒麟信安携手欧拉共推操作系统产业新发展

    摘要:作为在国产自主创新领域沉淀十余载的操作系统排头兵,麒麟信安将携手,立根铸魂,共推操作系统产业新发展。 2021年11月9日-10日,主题为立根铸魂,逐梦数字时代星辰...

    xavier 评论0 收藏0
  • SpringBoot热部署加持

    摘要:概述进行的开发过程中,我们很多时候经常需要重启服务器才能保证修改的源代码文件或者一些诸如的配置文件以及一些静态文件生效,这样耗时又低效。 showImg(https://segmentfault.com/img/remote/1460000015363888); 概述 进行SpringBoot的Web开发过程中,我们很多时候经常需要重启Web服务器才能保证修改的 源代码文件、或者一些...

    ixlei 评论0 收藏0
  • Elastic Search搜索引擎在SpringBoot中的实践

    摘要:注本文首发于公众号,可长按或扫描下面的小心心来订阅实验环境版本版本首先当然需要安装好环境,最好再安装上可视化插件来便于我们直观地查看数据。 showImg(https://segmentfault.com/img/remote/1460000015723674); 注: 本文首发于 My 公众号 CodeSheep ,可 长按 或 扫描 下面的 小心心 来订阅 ↓ ↓ ↓ showI...

    Me_Kun 评论0 收藏0

发表评论

0条评论

IT那活儿

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<