|
| 1 | +#!/bin/bash |
| 2 | +set -e |
| 3 | + |
| 4 | +# 基础 |
| 5 | +# export JAVA_HOME=/work/programs/jdk/jdk1.8.0_181 |
| 6 | +# export PATH=PATH=$PATH:$JAVA_HOME/bin |
| 7 | +# export CLASSPATH=$JAVA_HOME/jre/lib/rt.jar:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar |
| 8 | + |
| 9 | +DATE=$(date +%Y%m%d%H%M) |
| 10 | +# 基础路径 |
| 11 | +BASE_PATH=/work/projects/lab-41-demo01 |
| 12 | +# 编译后 jar 的地址。部署时,Jenkins 会上传 jar 包到该目录下 |
| 13 | +SOURCE_PATH=$BASE_PATH/build |
| 14 | +# 服务名称。同时约定部署服务的 jar 包名字也为它。 |
| 15 | +SERVER_NAME=lab-41-demo01 |
| 16 | +# 环境 |
| 17 | +PROFILES_ACTIVE=prod |
| 18 | +# 健康检查 URL |
| 19 | +HEALTH_CHECK_URL=http://127.0.0.1:8078/actuator/health/ |
| 20 | + |
| 21 | +# heapError 存放路径 |
| 22 | +HEAP_ERROR_PATH=$BASE_PATH/heapError |
| 23 | +# JVM 参数 |
| 24 | +JAVA_OPS="-Xms1024m -Xmx1024m -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=$HEAP_ERROR_PATH" |
| 25 | +# JavaAgent 参数。可用于配置 SkyWalking 等链路追踪 |
| 26 | +JAVA_AGENT= |
| 27 | + |
| 28 | +# 备份 |
| 29 | +function backup() { |
| 30 | + # 如果不存在,则无需备份 |
| 31 | + if [ ! -f "$BASE_PATH/$SERVER_NAME.jar" ]; then |
| 32 | + echo "[backup] $BASE_PATH/$SERVER_NAME.jar 不存在,跳过备份" |
| 33 | + # 如果存在,则备份到 backup 目录下,使用时间作为后缀 |
| 34 | + else |
| 35 | + echo "[backup] 开始备份 $SERVER_NAME ..." |
| 36 | + cp $BASE_PATH/$SERVER_NAME.jar $BASE_PATH/backup/$SERVER_NAME-$DATE.jar |
| 37 | + echo "[backup] 备份 $SERVER_NAME 完成" |
| 38 | + fi |
| 39 | +} |
| 40 | + |
| 41 | +# 最新构建代码 移动到项目环境 |
| 42 | +function transfer() { |
| 43 | + echo "[transfer] 开始转移 $SERVER_NAME.jar" |
| 44 | + |
| 45 | + # 删除原 jar 包 |
| 46 | + if [ ! -f "$BASE_PATH/$SERVER_NAME.jar" ]; then |
| 47 | + echo "[transfer] $BASE_PATH/$SERVER_NAME.jar 不存在,跳过删除" |
| 48 | + else |
| 49 | + echo "[transfer] 移除 $BASE_PATH/$SERVER_NAME.jar 完成" |
| 50 | + rm $BASE_PATH/$SERVER_NAME.jar |
| 51 | + fi |
| 52 | + |
| 53 | + # 复制新 jar 包 |
| 54 | + echo "[transfer] 从 $SOURCE_PATH 中获取 $SERVER_NAME.jar 并迁移至 $BASE_PATH ...." |
| 55 | + cp $SOURCE_PATH/$SERVER_NAME.jar $BASE_PATH |
| 56 | + |
| 57 | + echo "[transfer] 转移 $SERVER_NAME.jar 完成" |
| 58 | +} |
| 59 | + |
| 60 | +# 停止 |
| 61 | +function stop() { |
| 62 | + echo "[stop] 开始停止 $BASE_PATH/$SERVER_NAME" |
| 63 | + PID=$(ps -ef | grep $BASE_PATH/$SERVER_NAME | grep -v "grep" | awk '{print $2}') |
| 64 | + # 如果 Java 服务启动中,则进行关闭 |
| 65 | + if [ -n "$PID" ]; then |
| 66 | + # 正常关闭 |
| 67 | + echo "[stop] $BASE_PATH/$SERVER_NAME 运行中,开始 kill [$PID]" |
| 68 | + kill -15 $PID |
| 69 | + # 等待最大 60 秒,直到关闭完成。 |
| 70 | + for ((i = 0; i < 60; i++)) |
| 71 | + do |
| 72 | + sleep 1 |
| 73 | + PID=$(ps -ef | grep $BASE_PATH/$SERVER_NAME | grep -v "grep" | awk '{print $2}') |
| 74 | + if [ -n "$PID" ]; then |
| 75 | + echo -e ".\c" |
| 76 | + else |
| 77 | + echo '[stop] 停止 $BASE_PATH/$SERVER_NAME 成功' |
| 78 | + break |
| 79 | + fi |
| 80 | + done |
| 81 | + |
| 82 | + # 如果正常关闭失败,那么进行强制 kill -9 进行关闭 |
| 83 | + if [ -n "$PID" ]; then |
| 84 | + echo "[stop] $BASE_PATH/$SERVER_NAME 失败,强制 kill -9 $PID" |
| 85 | + kill -9 $PID |
| 86 | + fi |
| 87 | + # 如果 Java 服务未启动,则无需关闭 |
| 88 | + else |
| 89 | + echo "[stop] $BASE_PATH/$SERVER_NAME 未启动,无需停止" |
| 90 | + fi |
| 91 | +} |
| 92 | + |
| 93 | +# 启动 |
| 94 | +function start() { |
| 95 | + # 开启启动前,打印启动参数 |
| 96 | + echo "[start] 开始启动 $BASE_PATH/$SERVER_NAME" |
| 97 | + echo "[start] JAVA_OPS: $JAVA_OPS" |
| 98 | + echo "[start] JAVA_AGENT: $JAVA_AGENT" |
| 99 | + echo "[start] PROFILES: $PROFILES_ACTIVE" |
| 100 | + |
| 101 | + # 开始启动 |
| 102 | + BUILD_ID=dontKillMe nohup java -server $JAVA_OPS $JAVA_AGENT -jar $BASE_PATH/$SERVER_NAME.jar --spring.profiles.active=$PROFILES_ACTIVE & |
| 103 | + echo "[start] 启动 $BASE_PATH/$SERVER_NAME 完成" |
| 104 | +} |
| 105 | + |
| 106 | +# 健康检查 |
| 107 | +function healthCheck() { |
| 108 | + # 如果配置健康检查,则进行健康检查 |
| 109 | + if [ -n "$HEALTH_CHECK_URL" ]; then |
| 110 | + # 健康检查最大 60 秒,直到健康检查通过 |
| 111 | + echo "[healthCheck] 开始通过 $HEALTH_CHECK_URL 地址,进行健康检查"; |
| 112 | + for ((i = 0; i < 60; i++)) |
| 113 | + do |
| 114 | + # 请求健康检查地址,只获取状态码。 |
| 115 | + result=`curl -I -m 10 -o /dev/null -s -w %{http_code} $HEALTH_CHECK_URL || echo "000"` |
| 116 | + # 如果状态码为 200,则说明健康检查通过 |
| 117 | + if [ "$result" == "200" ]; then |
| 118 | + echo "[healthCheck] 健康检查通过"; |
| 119 | + break |
| 120 | + # 如果状态码非 200,则说明未通过。sleep 1 秒后,继续重试 |
| 121 | + else |
| 122 | + echo -e ".\c" |
| 123 | + sleep 1 |
| 124 | + fi |
| 125 | + done |
| 126 | + |
| 127 | + # 健康检查未通过,则异常退出 shell 脚本,不继续部署。 |
| 128 | + if [ ! "$result" == "200" ]; then |
| 129 | + echo "[healthCheck] 健康检查不通过,可能部署失败。查看日志,自行判断是否启动成功"; |
| 130 | + tail -n 10 nohup.out |
| 131 | + exit 1; |
| 132 | + # 健康检查通过,打印最后 10 行日志,可能部署的人想看下日志。 |
| 133 | + else |
| 134 | + tail -n 10 nohup.out |
| 135 | + fi |
| 136 | + # 如果未配置健康检查,则 slepp 60 秒,人工看日志是否部署成功。 |
| 137 | + else |
| 138 | + echo "[healthCheck] HEALTH_CHECK_URL 未配置,开始 sleep 60 秒"; |
| 139 | + sleep 60 |
| 140 | + echo "[healthCheck] sleep 60 秒完成,查看日志,自行判断是否启动成功"; |
| 141 | + tail -n 50 nohup.out |
| 142 | + fi |
| 143 | +} |
| 144 | + |
| 145 | +# 部署 |
| 146 | +function deploy() { |
| 147 | + cd $BASE_PATH |
| 148 | + # 备份原 jar |
| 149 | + backup |
| 150 | + # 停止 Java 服务 |
| 151 | + stop |
| 152 | + # 部署新 jar |
| 153 | + transfer |
| 154 | + # 启动 Java 服务 |
| 155 | + start |
| 156 | + # 健康检查 |
| 157 | + healthCheck |
| 158 | +} |
| 159 | + |
| 160 | +deploy |
0 commit comments