Spring Boot配合K8S实现平滑发版

Spring Boot配合K8S实现平滑发版

在我们平时的单体服务中,每次发版升级服务时,都会有不定时的停机服务时间,这种方式给用户带来极为不好的体验,用户用着用着,怎么突然访问不到了。随着K8S的兴趣,我们也顺应趋势,落地到生产上,基于K8S确实也给我们带来了方便,最显著的就是平滑发布、动态扩容。

基于readinessProbe探针不间断提供服务

如果,我们不开启readinessProbe探针,我们在发版时,依然会一边删除旧容器,一边启动新容器,这个时间差就是停止服务的时长。在配置之前,我们程序里面需要有一个健康检查的接口,这里,我选择自建一个接口

1
2
3
4
5
6
7
8
9
@RestController
@Slf4j
public class HealthController {

@RequestMapping("health")
public String health() {
log.info("health");
}
}

然后,在k8s配置文件中添加readinessProbe探针检查

1
2
3
4
5
6
7
8
9
10
readinessProbe:
httpGet:
path: /health
port: 8888
scheme: HTTP
initialDelaySeconds: 10 #在检查其运行状况之前,容器启动后需要等待多长时间提供外部访问。
timeoutSeconds: 1 #等待探针完成多长时间。如果超过时间,则认为探测失败。默认为1秒。最小值为1。
periodSeconds: 10 #执行探测的频率(以秒为单位)。默认为10秒。最小值为1
successThreshold: 1 #探测失败后,连续最小成功探测为成功。默认值为1。最小值为1。存活探针和启动探针内必须为1。
failureThreshold: 3 #探针进入失败状态时需要连续探测失败的最小次数


配置readinessProbe探针后,我们可以看到,在新容器启动之时,旧容器依然在运行中,当新容器启动成功后,会接管旧容器对外提供服务,然后删除旧容器。

基于preStop优雅关闭服务

前面,服务是不间断发布了,但是我们的旧容器里面的请求还没执行完,就被KILL掉了,这就很难保证数据的完整性了。所以,还要让我们的服务把请求处理完再关闭。默认:K8S发送停止命令给Pod时,Pod会先向容器中PID为1的进程发送系统信号SIGTERM,然后等待容器中的应用程序自行关闭,如果等待时间超过设置的超时时间或者默认超时时间(30s),就直接发送SIGKILL的系统信号强行KILL掉进程。所以,我们需要实现一个平滑关闭服务。在Spring Boot 2.3起,框架就支持优雅停机功能,只需要在配置文件配置即可

1
2
server:
shutdown: graceful

在项目根目录新建一个名为preStop.sh脚本,并复制一下代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#!/bin/bash

app=app.jar #应用名
function stop(){
PID=`ps aux | grep ${app} | grep -v grep | grep java | awk '{print $2}'`
echo "查询到相关进程列表ID为:${PID}"
pids=(${PID// /})
if [ ${pids[0]} ];then
echo "开始停止项目: ${app}!!!"
kill -2 ${pids[0]} #向应用发送SIGIN信号
sleep 2
else
echo "${app} 没有启动"
fi
}
stop


然后在Dockerfile中编写复制和授权命令

1
2
3
4
5
6
7
8
9
FROM java:8
WORKDIR /home
COPY *.jar /home
COPY *.sh /home
RUN chmod 777 /home/preStop.sh

ENV JAVA_OPTS="-server -Xmx2g -Xms2g"
ENTRYPOINT java -jar *.jar ${JAVA_OPTS}

接下来,根据实际情况,配置terminationGracePeriodSeconds时间,默认为30S,这里假设我服务停止时间超过了30秒,我为了让服务能平滑关闭,便设置为60

1
terminationGracePeriodSeconds: 60

最后再配置preStop

1
2
3
4
lifecycle:
preStop:
exec:
command:["/bin/sh","/home/preStop.sh"]

这样一来,既能让服务提供不间断服务,又能让服务平滑停机。

Spring Boot配合K8S实现平滑发版

https://blogs.52fx.biz/posts/3302087762.html

作者

eyiadmin

发布于

2022-05-25

更新于

2024-05-31

许可协议

评论