加载中...

java如何服务优雅从nacos中关闭


1.1 前言

在微服务时代,我们直接关闭一个pod,那这部分流量就无法得到正确处理,会影响部分用户.通常来说网关或者注册中心会将我们的服务保持一个心跳,过了心跳超时之后会自动摘除我们的服务,但是有一个问题就是超时时间可能是30秒也可能是60秒,虽然不会影响我们的系统,但是会产生用户轻微抖动。

如果我们在停止前执行一条命令,通知网关或者注册中心这台主机进行下线,那么注册中心就会标记这台主机已经下线,不进行流量转发,用户就不会有任何影响,这就是优雅停止,将滚动更新影响最小化

1.2 PreStop

这里以Nacos为例

Nacos 目前支持临时实例使用心跳上报方式维持活性,发送心跳的周期默认是 5 秒,Nacos 服务端会在 15 秒没收到心跳后将实例设置为不健康,

在 30 秒没收到心跳时将这个临时实例摘除。这里要注意30秒这个时间

nacos 服务手动下线方法

curl -X PUT "http://192.168.0.10:8848/nacos/v1/ns/instance?serviceName=java-test&clusterName=DEFAULT&groupName=test&ip=10.10.90.20&port=8888&enabled=false"

说明:

  • 192.168.0.10:8848 nacos注册地址
  • java-test 注册的应用名称
  • 10.10.90.20 注册的应用名称所在主机地址
  • 8888 注册的应用名称使用的端口号
  • enabled=false 下线,enabled=true 上线
  • namespaceId 命令空间,默认使用public命名空间则不写这个

这里是通过脚本先注入到镜像内 然后配置prestop来调用这个脚本

#!/bin/bash
NACOS_DISCOVERY_ADDR=`printenv | grep NACOS_DISCOVERY_ADDR | awk -F',' '{print $1}' | awk -F'=' '{print $2}'`
SERVER_NAME=${MY_POD_NAME}
PODIP=${POD_OWN_IP_ADDRESS}
PORT=`ss -tnl | grep 0.0.0.0 | awk '{print $4}' | awk -F':' '{print $2}'`

echo "输出必要的环境变量: ${NACOS_DISCOVERY_ADDR} ${SERVER_NAME} ${RUN_ENV} ${PODIP} ${PORT}"

result=$(curl -X PUT "http://${NACOS_DISCOVERY_ADDR}/nacos/v1/ns/instance?serviceName=${SERVER_NAME}&clusterName=DEFAULT&groupName=${RUN_ENV}&ip=${PODIP}&port=${PORT}&enabled=false"
)

echo "输出curl执行结果result:${result}"

if [ ${result} = "ok" ]; then
  echo "执行成功"
  sleep 45
  exit 0
else
  echo "执行失败"
  exit 1
fi

将脚本添加到基础镜像中

ADD preStop.sh /tmp/pre_stop.sh
RUN chmod 777 /tmp/pre_stop.sh

1.3 yaml添加配置

          lifecycle:
            preStop:
              exec:
                command:
                  - /bin/sh
                  - '-c'
                  - /tmp/pre_stop.sh

再次重启服务将会发现老服务会先处于下线状态 持续45s后才会正常关闭


文章作者: huhuhahei
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 huhuhahei !
评论
  目录