linux 服务一键更新回滚发布shell脚本
#!/bin/bash
set -e
DATE=$(date +%Y%m%d%H%M)
# 基础路径
BASE_PATH=/home/mico-service-gateway
# 编译后 jar包 的地址
SOURCE_PATH=$BASE_PATH/build
# 服务名称。同时约定部署服务的 jar 包名字也为它。
SERVER_NAME=mico-service-gateway-0.0.1-RELEASE.jar
# 健康检查 URL
#HEALTH_CHECK_URL=http://127.0.0.1:8078/actuator/health/
HEALTH_CHECK_URL=
# heapError 存放路径
HEAP_ERROR_PATH=$BASE_PATH/heapError
# JVM 参数
JAVA_OPS="-Xms1024m -Xmx1024m -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=$HEAP_ERROR_PATH"
# JavaAgent 参数。可用于配置 SkyWalking 等链路追踪
JAVA_AGENT=
# 备份
function backup() {
# 如果不存在,则无需备份
if [ ! -s $BASE_PATH/$SERVER_NAME ]; then
echo "[backup] $BASE_PATH/$SERVER_NAME 不存在,跳过备份"
# 如果存在,则备份到 backup 目录下,使用时间作为后缀
else
echo "[backup] 开始备份 $SERVER_NAME ..."
if [ ! -d $BASE_PATH/backup ];then
mkdir -p $BASE_PATH/backup
fi
cp -rf $BASE_PATH/$SERVER_NAME $BASE_PATH/backup/$SERVER_NAME-$DATE
echo "[backup] 备份 $SERVER_NAME 完成"
fi
}
# 最新构建代码 移动到项目环境
function transfer() {
echo "[transfer] 开始转移 $SERVER_NAME"
# 删除原 jar 包
if [ ! -s "$BASE_PATH/$SERVER_NAME" ]; then
echo "[transfer] $BASE_PATH/$SERVER_NAME 不存在,跳过删除"
else
echo "[transfer] 移除 $BASE_PATH/$SERVER_NAME 完成"
rm -rf $BASE_PATH/$SERVER_NAME;
fi
# 复制新 jar 包
echo "[transfer] 从 $SOURCE_PATH 中获取 $SERVER_NAME 并迁移至 $BASE_PATH ...."
cp -rf $SOURCE_PATH/$SERVER_NAME $BASE_PATH
echo "[transfer] 转移 $SERVER_NAME 完成"
}
# 停止
function stop() {
echo "[stop] 开始停止 $BASE_PATH/$SERVER_NAME"
PID=$(ps -ef | grep $BASE_PATH/$SERVER_NAME | grep -v "grep" | awk '{print $2}')
# 如果 Java 服务启动中,则进行关闭
if [ -n "$PID" ]; then
# 正常关闭
echo "[stop] $BASE_PATH/$SERVER_NAME 运行中,开始 kill [$PID]"
kill -15 $PID
# 等待最大 60 秒,直到关闭完成。
for ((i = 0; i < 60; i++))
do
sleep 1
PID=$(ps -ef | grep $BASE_PATH/$SERVER_NAME | grep -v "grep" | awk '{print $2}')
if [ -n "$PID" ]; then
echo -e ".\c"
else
echo '[stop] 停止 $BASE_PATH/$SERVER_NAME 成功'
break
fi
done
# 如果正常关闭失败,那么进行强制 kill -9 进行关闭
if [ -n "$PID" ]; then
echo "[stop] $BASE_PATH/$SERVER_NAME 失败,强制 kill -9 $PID"
kill -9 $PID
fi
# 如果 Java 服务未启动,则无需关闭
else
echo "[stop] $BASE_PATH/$SERVER_NAME 未启动,无需停止"
fi
}
# 启动
function start() {
# 开启启动前,打印启动参数
echo "[start] 开始启动 $BASE_PATH/$SERVER_NAME"
echo "[start] JAVA_OPS: $JAVA_OPS"
echo "[start] JAVA_AGENT: $JAVA_AGENT"
# 开始启动
BUILD_ID=dontKillMe nohup java -server $JAVA_OPS $JAVA_AGENT -jar $BASE_PATH/$SERVER_NAME &
sleep 3
PID=$(ps -ef | grep "$BASE_PATH/$SERVER_NAME" | grep -v grep | awk '{ print $2 }')
echo "[start] 启动 $BASE_PATH/$SERVER_NAME 完成,服务进程:$PID"
}
# 健康检查
function healthCheck() {
# 如果配置健康检查,则进行健康检查
if [ -n "$HEALTH_CHECK_URL" ]; then
# 健康检查最大 60 秒,直到健康检查通过
echo "[healthCheck] 开始通过 $HEALTH_CHECK_URL 地址,进行健康检查";
for ((i = 0; i < 60; i++))
do
# 请求健康检查地址,只获取状态码。
result=`curl -I -m 10 -o /dev/null -s -w %{http_code} $HEALTH_CHECK_URL || echo "000"`
# 如果状态码为 200,则说明健康检查通过
if [ "$result" == "200" ]; then
echo "[healthCheck] 健康检查通过";
break
# 如果状态码非 200,则说明未通过。sleep 1 秒后,继续重试
else
echo -e ".\c"
sleep 1
fi
done
# 健康检查未通过,则异常退出 shell 脚本,不继续部署。
if [ ! "$result" == "200" ]; then
echo "[healthCheck] 健康检查不通过,可能部署失败。查看日志,自行判断是否启动成功";
tail -n 10 nohup.out
exit 1;
# 健康检查通过,打印最后 10 行日志,可能部署的人想看下日志。
else
tail -n 10 nohup.out
fi
# 如果未配置健康检查,则 slepp 1 秒,人工看日志是否部署成功。
else
echo "[healthCheck] HEALTH_CHECK_URL 未配置,通过进程查询健康检查 开始 sleep 1 秒";
sleep 1
ps -ef | grep $BASE_PATH/$SERVER_NAME | grep -v grep
if [ $? -ne 0 ]
then
echo "[healthCheck] 目前服务进程已存在,暂定认为启动成功,查看日志,确定是否启动成功";
else
echo "[healthCheck] 目前未发现服务进程,启动失败,请查看日志,自行判断是否启动成功";
fi
tail -10f nohup.out
fi
}
#回退jar包
function jarRollBack() {
echo "[rollBack]回退开始 jar包为:`ls -l $BASE_PATH/backup| tail -n 1 | awk '{print $9}'`"
#获取最新的jar包
fileName=`ls -l $BASE_PATH/backup | tail -n 1 | awk '{print $9}'`;
#删除当前jar包,检查jar包是否存在,不存在,无需删除
if [ ! -s $BASE_PATH/$SERVER_NAME ];then
echo "[rollBack]jar包回退,发现真实jar包不存在,跳过删除操作"
else
rm -rf $BASE_PATH/$SERVER_NAME;
fi
#将最新jar包回归原位,待重新启动做准备
cp -rf $BASE_PATH/backup/$fileName $BASE_PATH/$SERVER_NAME;
echo "[rollBack]jar包回退完毕 "
}
#部署
function deploy() {
# cd $BASE_PATH
# 备份原 jar
backup
# 停止 Java 服务
stop
# 部署新 jar
transfer
# 启动 Java 服务
start
# 健康检查
healthCheck
}
#回退
function rollback() {
cd $BASE_PATH
# 停止 Java 服务
stop
# jar 包回退
jarRollBack
# 启动 Java 服务
start
# 健康检查
healthCheck
}
if [ $# -ne 1 ]
then
echo "服务一键启动或回退发生未知异常,偷偷告诉你:小子,动机不存,口令缺失"
exit 1
fi
# 如果是发布命令,则部署吧
if [ "$1" = "deploy" ]
then
deploy;
exit 1
fi
# 如果是回退命令,则回退吧
if [ "$1" = "rollback" ]
then
rollback;
exit 1
fi
echo "小子,干啥呢?果真动机不存,是想进局子吧?"
exit 1;