优雅停机(SpringBoot 2.3.0以上新特性)
我们在更新迭代是,可能需要手动发包,在停止包时,切记不要使用(kill -9)强制杀死进程,因为强制杀死进程的话,一些正在执行的请求,或者后台正在处理的逻辑,便会终止。1、例如正准备批量数据写入数据库,被强制杀死(该部分数据丢失)2、kafka消费正在提交位移1000(上次位移500),强行停止后位移提交失败,数据已经消费了,下次就会出现重新消费500-1000之间的数据。那么在不是强制结束进程的
我们在更新迭代是,可能需要手动发包,在停止包时,切记不要使用(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秒
更多推荐
所有评论(0)