deploy.sh 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. #!/bin/bash
  2. # ============================================================
  3. # 一键部署脚本
  4. # 用法: ./deploy.sh [admin|miniapp|all] [--skip-frontend]
  5. # 调试: bash -x ./deploy.sh
  6. # ============================================================
  7. APP_DIR="/data/app"
  8. CODE_DIR="/data/code/car-wash-java"
  9. BACKUP_DIR="/data/backup"
  10. LOG_DIR="/data/logs"
  11. HISTORY_FILE="/data/history"
  12. RED='\033[0;31m'
  13. GREEN='\033[0;32m'
  14. YELLOW='\033[1;33m'
  15. NC='\033[0m'
  16. log() { echo -e "[$(date '+%H:%M:%S')] $1"; }
  17. info() { log "${GREEN}INFO${NC} $1"; }
  18. warn() { log "${YELLOW}WARN${NC} $1"; }
  19. error() { log "${RED}ERROR${NC} $1"; }
  20. mkdir -p "$LOG_DIR" "$BACKUP_DIR"
  21. info "开始部署..."
  22. # ---- 参数解析 ----
  23. TARGET="${1:-all}"
  24. SKIP_FRONTEND=false
  25. [ "$2" = "--skip-frontend" ] || [ "$1" = "--skip-frontend" ] && SKIP_FRONTEND=true
  26. # ---- 拉取最新代码 ----
  27. info "拉取最新代码..."
  28. cd "$CODE_DIR" || { error "无法进入 $CODE_DIR"; exit 1; }
  29. git pull origin master || { error "git pull 失败"; exit 1; }
  30. # ---- 前端构建 ----
  31. if [ "$SKIP_FRONTEND" = false ] && [ "$TARGET" != "miniapp" ]; then
  32. info "构建管理后台前端 (admin-web)..."
  33. (cd "$CODE_DIR/admin-web" && npm run build) || { error "admin-web 构建失败"; exit 1; }
  34. info "构建 H5 前端 (admin-h5)..."
  35. (cd "$CODE_DIR/admin-h5" && npm run build) || { error "admin-h5 构建失败"; exit 1; }
  36. info "前端构建完成"
  37. fi
  38. # ---- Maven 打包 ----
  39. if [ "$TARGET" = "miniapp" ]; then
  40. info "Maven 打包 (仅 miniapp)..."
  41. (cd "$CODE_DIR" && mvn clean package -DskipTests -pl car-wash-miniapp -am) || { error "Maven 打包失败"; exit 1; }
  42. else
  43. info "Maven 打包..."
  44. (cd "$CODE_DIR" && mvn clean package -DskipTests) || { error "Maven 打包失败"; exit 1; }
  45. fi
  46. # ---- 备份并复制 jar ----
  47. backup_and_copy() {
  48. local module=$1
  49. local jar_src="$CODE_DIR/$module/target/${module}-0.0.1-SNAPSHOT.jar"
  50. local jar_dst="$APP_DIR/${module}-0.0.1-SNAPSHOT.jar"
  51. if [ ! -f "$jar_src" ]; then
  52. error "未找到 jar 文件: $jar_src"
  53. exit 1
  54. fi
  55. if [ -f "$jar_dst" ]; then
  56. cp "$jar_dst" "$BACKUP_DIR/${module}-0.0.1-SNAPSHOT.jar.$(date +%Y%m%d_%H%M%S)"
  57. info "已备份 $module (保留最近 5 个)"
  58. ls -t "$BACKUP_DIR/${module}"-*.jar 2>/dev/null | tail -n +6 | xargs -r rm -f
  59. fi
  60. cp "$jar_src" "$jar_dst"
  61. info "$module jar 已复制到 $APP_DIR"
  62. }
  63. # ---- 重启服务 (使用原版 wash-restart.sh 的 PID 检测逻辑) ----
  64. restart_service() {
  65. local module=$1
  66. local jar_file="${module}-0.0.1-SNAPSHOT.jar"
  67. local start_log="$LOG_DIR/${module}.log"
  68. info "正在停止 $module ..."
  69. # 用原版脚本的 grep 方式: grep java | grep 模块名
  70. local pid=$(ps -ef | grep java | grep "$module" | grep -v grep | awk '{print $2}')
  71. if [ -n "$pid" ]; then
  72. # 多 pid 情况:逐个处理
  73. for p in $pid; do
  74. info "终止进程 $module (pid=$p)..."
  75. kill "$p" 2>/dev/null
  76. # 等待 10 秒
  77. for i in $(seq 1 10); do
  78. if ! kill -0 "$p" 2>/dev/null; then
  79. info "进程 $p 已退出"
  80. break
  81. fi
  82. sleep 1
  83. done
  84. # 没退出就强制 kill
  85. if kill -0 "$p" 2>/dev/null; then
  86. warn "强制终止 $p"
  87. kill -9 "$p" 2>/dev/null
  88. sleep 1
  89. fi
  90. done
  91. else
  92. info "$module 未在运行"
  93. fi
  94. # 确认端口释放
  95. info "启动 $module ..."
  96. local cert_arg=""
  97. if [ "$module" = "car-wash-admin" ]; then
  98. cert_arg="-Dwechat.payment.certPath=/data/wash-pem/apiclient_cert.pem -Dwechat.payment.keyPath=/data/wash-pem/apiclient_key.pem"
  99. fi
  100. cd "$APP_DIR"
  101. nohup java -jar -Dspring.profiles.active=prod $cert_arg "$jar_file" > "$start_log" 2>&1 &
  102. sleep 5
  103. local new_pid=$(ps -ef | grep java | grep "$module" | grep -v grep | awk '{print $2}')
  104. if [ -n "$new_pid" ]; then
  105. info "$module 启动成功 (pid=$new_pid)"
  106. echo "$(date) $module restarted" >> "$HISTORY_FILE"
  107. else
  108. error "$module 可能启动失败,查看日志:"
  109. echo "--- $start_log ---"
  110. tail -30 "$start_log"
  111. echo "--- end ---"
  112. exit 1
  113. fi
  114. }
  115. # ---- 执行部署 ----
  116. case "$TARGET" in
  117. admin)
  118. backup_and_copy "car-wash-admin"
  119. restart_service "car-wash-admin"
  120. ;;
  121. miniapp)
  122. backup_and_copy "car-wash-miniapp"
  123. restart_service "car-wash-miniapp"
  124. ;;
  125. all)
  126. backup_and_copy "car-wash-admin"
  127. backup_and_copy "car-wash-miniapp"
  128. restart_service "car-wash-admin"
  129. restart_service "car-wash-miniapp"
  130. ;;
  131. *)
  132. error "未知模块: $TARGET (可选: admin | miniapp | all)"
  133. exit 1
  134. ;;
  135. esac
  136. echo "========================================"
  137. info "部署完成"
  138. echo "========================================"