公司项目使用 Spirng Cloud Alibaba,使用 Nacos 注册中心,部署在华为云的 CCE(基于 K8s)中。为节约资源,开发测试环境的服务只部署了一个节点。这时出现一个问题:每次节点部署,系统就会出现服务短暂不可用的情况。
原因:K8s 支持滚动部署,但如果只有一个节点,容器中 Java 应用有启动时间,从启动到成功注册进 Nacos 有一个时间间隔,不是马上就可用。此时 K8s 杀掉老的服务,并将流量切到还没成功注册进 Nacos 中的新服务时,服务请求不能处理,服务就不可用。
解决方式就是加一个就绪指针,当时新服务已成功注册成功到 Nacos 中时,再杀掉老服务,将流量切换到新服务。
就绪检查方式有很多种,我选择的是「HTTP 请求检查」。所以我需要为每个服务添加一个「就绪接口」,用于判断服务是否已成功注册进 Nacos。我们服务有很多个,我不想每个服务添加一个相同作用的接口,想对当前业务无侵入。我利用 starter + spring-boot-actuator 实现。
新建一个监控 starter,starter 中添加自定义 spring-boot-actuator 端点,让部署服务引用 starter。
starter 核心代码:
import org.springframework.beans.factory.annotation.Autowired; |
K8s 具体配置:
readinessProbe: |
注意:不要设置启动探针(startupProbe),启动探针在检测失败时,会重启容器。存活探针(livenessProbe)首次检查时间也要设置长一点,要预估在服务已就绪之后。