在最近的工作中,我们已经使用阿里云NAS将需要发布的jar包统一上传到NAS中,但是部署的时候还是需要每个服务器去单独启动,比较麻烦。所以准备写一个批量自动部署的脚本。
背景
1.我们使用的Spring Cloud微服务
2.现在服务的部署方式是单独n台服务器部署eureka+nginx+nacos(每台机器配置和服务相同)。单独的m台部署gateway、user等业务服务(每台机器配置和服务相同)。
3.没一个业务服务单独在基础文件夹下新建文件夹,且包含三个文件,一个jar包,对应的Dockerfile,启动的start_xxx.sh
理清思路
1.必须要有基础文件夹路径
2.必须要有m台业务服务器的ssh信息
3.必须要知道所有业务服务的启动sh(启动时)、docker容器名称(重启时)
4.有这这些信息之后,我们可以ssh到对应服务器执行启动/重启指令
实现
前提条件
1.使用jq解析json格式的配置文件(为什么不用yml),安装jq
2.使用sshpass连接服务器(是不是可以用其它免密登录代替),安装sshpass
shell脚本
#/bin/bash
## get param from commond
declare -a params
index=0
for i in "$@"; do
params[$index]=$i
let "index++"
done
startMark="s"
# echo "接收到的指令为 ${params[0]}"
start=0
if [ "${params[0]}" = "$startMark" ]
then let "start=1"
fi
## read from config
basePath=$(jq .basePath test.json)
declare -a bizCommond;
declare -a bizValid;
contain=0
bizIndex=0
while read name path containerName port serverName; do
contain=$(echo "${params[@]}" | grep -wq "$name" && echo 1 || echo 0)
# echo "compare result is $contain"
if (($contain == 1))
then
if (($start == 1))
then
bizCommond[$bizIndex]=$path
else
bizCommond[$bizIndex]=$containerName
fi
bizValid[$bizIndex]=":$port/$serverName/actuator/info"
let "bizIndex++"
fi
done < <(cat test.json | jq -r '.biz[]|"\(.name) \(.path) \(.containerName) \(.port) \(.serverName)"')
if (( ${#bizCommond[*]} < 1))
then exit
fi
while read ip port user pass ; do
echo "连接到$ip部署"
for ((i=0; i<${#bizCommond[*]}; i++))
do
echo "开始启动"
if (($start == 1))
then
commond=" cd $basePath && ${bizCommond[$i]} "
else
commond="docker restart ${bizCommond[$i]} "
fi
echo "执行启动指令 $commond"
sshpass -p $pass ssh -p $port $user@$ip "$commond"
validCommond="curl -I -m 10 -o /dev/null -s -w %{http_code} http://$ip${bizValid[$i]}"
echo "执行检查指令 $validCommond"
result=$($validCommond)
echo "检查结果为:$result"
while [[ "$result" == "000" ]]; do
sleep 3
result=$($validCommond)
echo "检查结果为:$result"
done
echo "启动完成"
sleep 2
done
done < <(cat test.json | jq -r '.machine[]|"\(.ip) \(.port) \(.user) \(.pass)"')
配置文件
{
"basePath": "/home/app/",
"biz":
[
{
"name": "x",
"path": "./xxx/start_xxx.sh",
"containerName": "xxx",
"port": "8010",
"serverName": "xxx-server"
},
{
"name": "y",
"path": "./yyy/start_yyy.sh",
"containerName": "yyy",
"port": "8100",
"serverName": "yyy-server"
}
],
"machine":
[
{
"ip":"192.168.0.105",
"port": 22,
"user":"root",
"pass":"123456"
}
]
}
json数据释义
{
"basePath": "/home/app/", //基础工作目录
"biz": // 业务服务配置
[
{
"name": "x", // 服务别名,在使用命令时匹配名称
"path": "./xxx/start_xxx.sh", // 启动执行的脚本
"containerName": "xxx", // docker容器名称
"port": "8010", // 监听的端口
"serverName": "xxx-server" // 服务名称-Spring Boot项目中spring.application.name
}
],
"machine": // 部署的服务器
[
{
"ip":"192.168.0.105", // 服务器ip地址
"port": 22, // 服务器ssh端口
"user":"root", // 服务器用户名
"pass":"123456" // 服务器密码
}
]
}
使用
## 启动
./xxx.sh s yyy zzz
## 重启
./xxx.sh r yyy zzz
未竞工作
1.结合Eureka,先将Eureka的状态变为DOWN之后在执行启动/重启
2.校验服务是否启动还需要校验Eureka的状态是否是UP(Eureka的接口是xml的o(╥﹏╥)o)
3.需要在启动服务时传入参数/环境变量还未做
网友评论