Spring Boot配合K8S实现平滑发版
在我们平时的单体服务中,每次发版升级服务时,都会有不定时的停机服务时间,这种方式给用户带来极为不好的体验,用户用着用着,怎么突然访问不到了。随着K8S的兴趣,我们也顺应趋势,落地到生产上,基于K8S确实也给我们带来了方便,最显著的就是平滑发布、动态扩容。
基于readinessProbe探针不间断提供服务
如果,我们不开启readinessProbe
探针,我们在发版时,依然会一边删除旧容器,一边启动新容器,这个时间差就是停止服务的时长。在配置之前,我们程序里面需要有一个健康检查的接口,这里,我选择自建一个接口
1 | @RestController |
然后,在k8s配置文件中添加readinessProbe
探针检查
1 | readinessProbe: |
配置readinessProbe探针后,我们可以看到,在新容器启动之时,旧容器依然在运行中,当新容器启动成功后,会接管旧容器对外提供服务,然后删除旧容器。
基于preStop优雅关闭服务
前面,服务是不间断发布了,但是我们的旧容器里面的请求还没执行完,就被KILL掉了,这就很难保证数据的完整性了。所以,还要让我们的服务把请求处理完再关闭。默认:K8S发送停止命令给Pod时,Pod会先向容器中PID为1的进程发送系统信号SIGTERM,然后等待容器中的应用程序自行关闭,如果等待时间超过设置的超时时间或者默认超时时间(30s),就直接发送SIGKILL的系统信号强行KILL掉进程。所以,我们需要实现一个平滑关闭服务。在Spring Boot 2.3
起,框架就支持优雅停机功能,只需要在配置文件配置即可
1 | server: |
在项目根目录新建一个名为preStop.sh
脚本,并复制一下代码
1 | #!/bin/bash |
然后在Dockerfile
中编写复制和授权命令
1 | FROM java:8 |
接下来,根据实际情况,配置terminationGracePeriodSeconds
时间,默认为30S,这里假设我服务停止时间超过了30秒,我为了让服务能平滑关闭,便设置为60
1 | terminationGracePeriodSeconds: 60 |
最后再配置preStop
1 | lifecycle: |
这样一来,既能让服务提供不间断服务,又能让服务平滑停机。
Spring Boot配合K8S实现平滑发版