記一次問題處理-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

相關文章
相關標籤/搜索