Shell 脚本实战:Consul 服务注册和注销的最佳实践
作者:小毛驴的烂笔头
- 2023-04-24 广东
本文字数:3275 字
阅读完需:约 11 分钟
业务爸爸需求: 写一个脚本用于向 Consul 注册或注销服务。
Consul API 实现服务的注册和注销功能
拿到这个需求,我第一时间想到是用 curl 调用 Consul API 实现服务的注册和注销功能。 如下:
#!/bin/bash
CONSUL_TOKEN="<your_token_here>"
CONSUL_URL="http://localhost:8500"
function register_service {
curl \
--request PUT \
--header "Content-Type: application/json" \
--header "X-Consul-Token: ${CONSUL_TOKEN}" \
--data "@- ${CONSUL_URL}/v1/agent/service/register" <<EOF
{
"ID": "${1}",
"Name": "${2}",
"Address": "${3}",
"Port": ${4}
}
EOF
}
function deregister_service {
curl \
--request PUT \
--header "X-Consul-Token: ${CONSUL_TOKEN}" \
"${CONSUL_URL}/v1/agent/service/deregister/${1}"
}
# example usage
register_service "my-service" "My Service" "localhost" 8080
deregister_service "my-service"
复制代码
在这个实现中,我们将认证 token 存储在 CONSUL_TOKEN 变量中,并在 curl 请求中使用--header "X-Consul-Token: ${CONSUL_TOKEN}"来添加它。
这个是可以实现业务爸爸的需求, 但是,这种实现有以下几个问题:
不能批量添加相同的类型的指标。
唯一 ID 需要手动维护。
没有配置文件留底,虽然三节点的 consul 集群很小概率同时出问题, 但是有留底还是一个很好习惯。
基于这个几个点, 写入下面实现脚本。
register 和 deregister 实现
#!/bin/bash
# author 小毛驴
#
SHELL_DIR=$(cd $(dirname $0);pwd)
BACKUP_DIR=${SHELL_DIR}"/consulbackup"
SOURCEFILE=${SHELL_DIR}"/origin.json"
LOGFILE=${SHELL_DIR}"/add.log"
BASESVCRIR=/data/consul/config/
TOKENFILE=/data/consul/consul_token.yaml
OPTION=${OPTION:="1"}
ENV=${ENV:="prod"}
PROJECT=${PROJECT:="fb"}
MODULE=${MODULE:="api"}
SERVICENAME=${SERVICENAME:="node-exporter"}
NAME=${NAME:="core"}
TAG=${TAG:="node-exporter"}
IPADDRS=""
IPADDR=""
PORT=${PORT:="9520"}
LEGAL_IP="^([0-9]{1,2}|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.([0-9]{1,2}|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.([0-9]{1,2}|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.([0-9]{1,2}|1[0-9][0-9]|2[0-4][0-9]|25[0-5])$"
if [ ! -e "${BACKUP_DIR}" ];then
mkdir -p ${BACKUP_DIR}
fi
function usage(){
echo -e "\nUsage: $0 <option> <value>"
echo -e "\n option:"
echo -e "\n -o,--option option name, default 1:add , 2:delete"
echo -e "\n -e,--env env name, default prod"
echo -e "\n -p,--project project name, default fb"
echo -e "\n -m,--module module name, default api"
echo -e "\n -n,--name api name, default core"
echo -e "\n -s,--svcname serviceName name, default node-exporter"
echo -e "\n -t,--tag tag name, default node-exporter"
echo -e "\n -a,--address ip address, eg 1.1.1.1|2.2.2.2 default '' [Require]"
echo -e "\n -i,--interface interface num default 9520"
echo -e "\n -h,--help help"
}
function checkIp()
{
#正则表达式检验 ip 地址
[[ $1 =~ $LEGAL_IP ]]
if [ $? -gt 0 ]; then
echo "$1 is an error ip fromat"
exit 10
fi
}
function svcDeregister() {
if [ ! -e "$1" ];then
echo "$1 not exit, please check!"
else
/bin/consul services deregister -token-file=${TOKENFILE} $1
fi
}
function svcRegister() {
if [ ! -e "$1" ];then
echo "$1 not exit, please check!"
else
/bin/consul services register -token-file=${TOKENFILE} $1
fi
}
function genJson() {
cat > "${SERVICENAME}-${ENV}-${PROJECT}-${MODULE}-${NAME}-${IPADDR}.json" <<EOF
{
"service": {
"id": "${SERVICENAME}-${ENV}-${PROJECT}-${MODULE}-${NAME}-${IPADDR}",
"name": "${SERVICENAME}",
"tags": [
"${TAG}"
],
"address": "${IPADDR}",
"port": ${PORT},
"meta": {
"name": "${NAME}-${IPADDR}",
"module": "${MODULE}",
"project": "${PROJECT}",
"env": "${ENV}"
},
"check": {
"http": "http://${IPADDR}:${PORT}/metrics",
"interval": "10s"
},
"weights": {
"passing": 10,
"warning": 1
}
}
}
EOF
}
function removeJson() {
mv "${SERVICENAME}-${ENV}-${PROJECT}-${MODULE}-${NAME}-${IPADDR}.json" ${BACKUP_DIR}
}
function main() {
if (($# == 0));then
usage
exit
fi
cd ${SHELL_DIR}
while [ -n "$1" ];do
case $1 in
-o|--option )
OPTION=$2
shift
;;
-e|--env )
ENV=$2
shift
;;
-p|--project )
PROJECT=$2
shift
;;
-m|--module )
MODULE=$2
shift
;;
-n|--name )
NAME=$2
shift
;;
-s|--svcname )
SERVICENAME=$2
shift
;;
-t|--tag )
TAG=$2
shift
;;
-a|--address )
IPADDRS=$2
shift
;;
-i|--interface )
PORT=$2
shift
;;
-h|--help )
usage
exit
;;
*)
echo -e "\n$1 unknow an option"
usage
exit
esac
shift
done
if [ "${IPADDRS}"x == ""x ];then
echo -e "\n-a|--address option is Require"
usage
exit
fi
SVCRIR="${BASESVCRIR}/${SERVICENAME}"
if [ ! -e "${SVCRIR}" ];then
mkdir -p ${SVCRIR}
fi
cd ${SVCRIR}
hosts=($(echo ${IPADDRS} | sed 's/|/ /g'))
for(( i=0;i<${#hosts[@]};i++))
do
echo ${hosts[$i]}
checkIp ${hosts[$i]}
IPADDR="${hosts[$i]}"
if [[ "${OPTION}"x == "1"x ]]; then
genJson
#statements
svcRegister "${SERVICENAME}-${ENV}-${PROJECT}-${MODULE}-${NAME}-${IPADDR}.json"
fi
if [[ "${OPTION}"x == "2"x ]]; then
#statements
svcDeregister "${SERVICENAME}-${ENV}-${PROJECT}-${MODULE}-${NAME}-${IPADDR}.json"
removeJson
fi
done
}
main $@
复制代码
这个脚本首先定义了 BACKUP_DIR,BASESVCRIR 和 TOKENFILE 等路径。
用法
./register-service.sh [OPTIONS]
复制代码
参数
-h, --help: 显示帮助信息并退出。
-o, -option: 1 register ; 2 deregister
-e,--env 环境标识, default prod
-p,--project 项目名字, default fb
-m,--module 业务模块名, default api
-n,--name 模块下面的应用名, default core
-s,--svcname service 名字, default node-exporter
-t,--tag tag 名字, default node-exporter
-a,--address 需要注册到该服务的地址,多个以“|”分开,, eg 1.1.1.1|2.2.2.2 default '' [Require],必须提供
-i,--interface 需要注册的端口 9520
复制代码
./register-service.sh -o 1 -e prod -p fb -m ops -n consul-ops -s consul_exporter-t consul_exporter -a "10.2.0.6|10.2.0.10|10.2.0.41" -i 9107
划线
评论
复制
发布于: 刚刚阅读数: 4
版权声明: 本文为 InfoQ 作者【小毛驴的烂笔头】的原创文章。
原文链接:【http://xie.infoq.cn/article/22c73b71fb3c56a188de06f96】。文章转载请联系作者。
小毛驴的烂笔头
关注
还未添加个人签名 2018-12-12 加入
还未添加个人简介
评论