Spring Boot 1.X 优雅停机的一种实现方式

目前部署在k8s上的springboot应用通过RollingUpdate的方式更新应用时发现以下情况:

一个新pod起来并经过health check检查可以接收流量之后会删除一个老pod。但是,删除老pod时,虽然没有新的流量进入老pod,该老pod中的java进程还有一些业务没有处理完毕就直接被kill掉。

因此,我们需要做到当新pod起来之后,老pod不接收新流量,但是已经在处理的流量请求处理完之后才能删除老pod。

其实,k8s本身对于pod是有一个terminationGracePeriodSeconds的配置项(默认是30秒)。当采用RollingUpdate方式更新应用时,一个新pod起来并经过health check后(如果配置了health check),则会通知k8s终止一个pod。k8s终止pod的生命周期如下(共5步):

  1. Pod被设置为Terminating状态,并从k8s的service/endpoint列表中删除。此时,Pod停止获得新流量。在Pod中运行的容器不会受到影响。
  2. preStop Hook被执行(如果deployment yaml中配置该项,默认没有配置)。preStop Hook是一个发送到Pod中的容器特殊命令或Http请求。
  3. K8S向Pod中的容器发送SIGTERM信号。这个信号让容器知道它们很快就会被关闭。
    SIGTERM比较友好,进程能捕捉这个信号, 根据您的需要来关闭程序。在关闭程序之前,您可以结束打开的记录文件和完成正在做的任务。 在某些情况下, 假如进程正在进行作业而且不能中断,那么进程可以忽略这个 SIGTERM信号。相对于kill ${pid}命令。
    对于SIGKILL信号,进程是不能忽略的。 这是一个 '“我不管您在做什么,立刻停止”'的信号。 假如您发送SIGKILL信号给进程,
    FreeBSD就将进程停止在那里。相对于kill -9 ${pid}命令
    SpringBoot应用的java process捕获到该SIGTERM信号时就会开始正常关闭自己。
  4. K8S等待优雅的终止(等待时间terminationGracePeriodSeconds)

注意:

  • 等待优雅终止,在时间上是与preStop Hook和SiGTERM信号并行的。k8s不会等待preStop Hook完成。
  • 如果应用程序完成关闭并在terminationGracePeriod(假设30S)完成之前退出,k8s是不会等30S而是立即进入下一步。
  • 如果POD中的应用需要30秒才能关闭,则需要相应增加优雅终止期限。 K8S向Pod发送
  1. SIGKILL信号,并删除Pod

如果容器在优雅终止宽限期后仍在运行,则会发送SIGKILL信号并强制删除。 此时,相应的Kubernetes对象也会被清除。

从上面的步骤我们可以看出,k8s是终止优雅停机的;但是,还需要应用配合。如上面第4步第2条中所说的,应用在terminationGracePeriod之前就完成关闭,则pod会直接被删除。所以,我需要在SpringBoot应用在接收到SIGTERM信号退出应用时,做以下几点:

停止接收流量/请求。

注意:虽然上面第1步中说是会Pod从service/endpoint列表中删除,不再接收流量。那只是对通过k8s service访问pod方式的流量请求,例如zuul。对于springcloud中的其他的springboot应用,它们之间的调用是通过pod ip直接访问的。因此这时候需要应用本事停止接收流量/请求。温柔的终止线程池。

等待线程池终止。
相关代码实现如下:


import org.apache.catalina.connector.Connector;
import org.apache.tomcat.util.threads.ThreadPoolExecutor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.SpringApplication;
import org.springframework
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值