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