记一次问题处理-20190610(Consul)

🎯背景

先说一下架构:标准Spring Cloud,注册中心使用Consul,Docker容器化部署。html

问题就出如今这个Consul和Docker的结合,现象就是在程序从新发布时,新的容器启动,在stop旧容器的时候,Consul注册中心的旧实例没有退出,并且咱们容器是随机IP地址,致使每次重启就会有无效的客户端,虽然不影响使用,可是在web端看到也是很烦的。java

🎯解决方案

在网上找了解决方案,这篇以为不错:www.cnblogs.com/sparkdev/p/…web

#!/usr/bin/env bash

set -x
pid=0
 # 处理逻辑
term_handler() {
  if [ $pid -ne 0 ]; then
    kill -SIGTERM "$pid"
    wait "$pid"
  fi
  exit 143; # 128 + 15 -- SIGTERM
}
# 监听
trap 'kill ${!}; term_handler' SIGTERM
 # 启动Consul Client,本地调试,省略实际链接注册中心
nohup consul agent -data-dir /root/consul >/dev/null &
 # 取得consul进程编号
pid="$!"
 # 注意要保持后台运行,不然会阻塞
java -jar /app.jar --spring.profiles.active=dev &
 # wait forever
while true
do
  tail -f /dev/null & wait ${!}
done
复制代码

🎯结论

在程序从新发布项目,容器会把以前容器执行docker stop操做,这个操做只会给pid为1的进程(在咱们项目中就是docker_entrypoint.sh脚本执行的进程)发送SIGTERM信号,致使容器中Consul进程没有收到SIGTERM信号,被kill -9 强制杀掉,因此Consul没有给注册中心推送下线的信号,致使有注册中心有不少僵尸客户端。上面解决方式是在Consul进程启动后标记进程编号,并监听自身的SIGTERM信号,收到信号,在处理函数中给Consul进程编号传递SIGTERM,让Consul优雅的退出。spring

相关文章
相关标签/搜索