我们在更新迭代是,可能需要手动发包,在停止包时,切记不要使用(kill -9)强制杀死进程,因为强制杀死进程的话,一些正在执行的请求,或者后台正在处理的逻辑,便会终止。
1、例如正准备批量数据写入数据库,被强制杀死(该部分数据丢失)
2、kafka消费正在提交位移1000(上次位移500),强行停止后位移提交失败,数据已经消费了,下次就会出现重新消费500-1000之间的数据。
那么在不是强制结束进程的情况下,我们如何保证项目中待执行的任务,执行完毕后杀死进程啦。
实现这个功能的需求,专业术语为优雅停机
如何实现这个优雅停机?
1、引入SpringBoot需要大于2.3.0.RELEASE版本,例如下面

  <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.5.4</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

然后在配置文件中增加如下配置:

server:
  port: 9091
  ## 开启优雅停机, 如果不配置是默认IMMEDIATE, 立即停机
  shutdown: graceful
  ## 优雅停机宽限期时间
spring:
  lifecycle:
  timeout-per-shutdown-phase: 15s

以上配置完成我们就已经大功告成,只需测试,停机宽限时间为20秒,如果程序处理耗时超过20秒的话,程序已经会处理失败,所以这个时间需要根据你项目中处理任务的耗时来设置。
下面进入测试阶段:

@GetMapping("sleep")
public String sleep(Integer timeout){
    try{
        log.info("begin sleep:{}",timeout);
        TimeUnit.SECONDS.sleep(timeout);
        log.info("end sleep:{}",timeout);
    }catch(Exception e){
        e.printStackTrace();
    }
    return "sleep:" + timeout;
}

测试思路,我们启动项目,调用接口,设置不同的休眠时间。调用接口后,立马停止项目,看是否会返回数据。例如操作两次,休眠时间设置15秒,40秒,操作结果如下
15秒
在这里插入图片描述
我们在2021-12-28 16:20:41之前时候停止了项目,但是后面还是执行了结束休眠的日志打印。
40秒
在这里插入图片描述

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐