Forráskód Böngészése

部署脚本优化

skyline 1 napja
szülő
commit
f860fb2add
1 módosított fájl, 142 hozzáadás és 59 törlés
  1. 142 59
      deploy.sh

+ 142 - 59
deploy.sh

@@ -1,8 +1,9 @@
 #!/bin/bash
 
 # ============================================================
-# 一键部署脚本
-# 用法: ./deploy.sh [admin|miniapp|all] [--skip-frontend]
+# 一键部署脚本 (2核4G 低配服务器优化版)
+# 用法: ./deploy.sh [admin|miniapp|all] [--skip-frontend] [--no-stop]
+#       --no-stop  构建前不停止服务 (零停机,JVM 已限制内存)
 # 调试: bash -x ./deploy.sh
 # ============================================================
 
@@ -24,39 +25,140 @@ error() { log "${RED}ERROR${NC} $1"; }
 
 mkdir -p "$LOG_DIR" "$BACKUP_DIR"
 
-info "开始部署..."
+# ============================================================
+# 资源限制配置 (2核4G 服务器)
+# ============================================================
+
+# ---- 构建阶段 ----
+NODE_MAX_MEM="${NODE_MAX_MEM:-1024}"      # Node 最大 old-space MB
+MAVEN_XMX="${MAVEN_XMX:-512}"             # Maven JVM 最大堆 MB
+MAVEN_XMS="${MAVEN_XMS:-128}"             # Maven JVM 初始堆 MB
+MAVEN_THREADS="${MAVEN_THREADS:-1}"       # Maven 编译线程数
+
+# ---- 运行时 JVM (admin 模块) ----
+ADMIN_XMX="${ADMIN_XMX:-512}"             # 最大堆 MB (含 POI Excel 处理)
+ADMIN_XMS="${ADMIN_XMS:-128}"             # 初始堆 MB
+ADMIN_META="${ADMIN_META:-128}"           # 元空间上限 MB
+ADMIN_CODE_CACHE="${ADMIN_CODE_CACHE:-64}" # JIT 代码缓存 MB
+ADMIN_XSS="${ADMIN_XSS:-256}"             # 线程栈 KB
+
+# ---- 运行时 JVM (miniapp 模块) ----
+MINIAPP_XMX="${MINIAPP_XMX:-384}"
+MINIAPP_XMS="${MINIAPP_XMS:-128}"
+MINIAPP_META="${MINIAPP_META:-128}"
+MINIAPP_CODE_CACHE="${MINIAPP_CODE_CACHE:-64}"
+MINIAPP_XSS="${MINIAPP_XSS:-256}"
+
+# 低优先级包装器
+low_prio() {
+    nice -n 19 ionice -c 2 -n 7 "$@"
+}
 
 # ---- 参数解析 ----
 TARGET="${1:-all}"
 SKIP_FRONTEND=false
-[ "$2" = "--skip-frontend" ] || [ "$1" = "--skip-frontend" ] && SKIP_FRONTEND=true
+NO_STOP=false
+for arg in "$@"; do
+    [ "$arg" = "--skip-frontend" ] && SKIP_FRONTEND=true
+    [ "$arg" = "--no-stop" ] && NO_STOP=true
+done
+
+info "开始部署 (目标=$TARGET, 零停机=$NO_STOP)"
+info "Node:${NODE_MAX_MEM}M | Maven:${MAVEN_XMX}M | Admin-JVM:${ADMIN_XMX}M | Miniapp-JVM:${MINIAPP_XMX}M"
 
-# ---- 拉取最新代码 ----
+# ---- 拉取代码 ----
 info "拉取最新代码..."
 cd "$CODE_DIR" || { error "无法进入 $CODE_DIR"; exit 1; }
-git pull origin master || { error "git pull 失败"; exit 1; }
+low_prio git pull origin master || { error "git pull 失败"; exit 1; }
 
-# ---- 前端构建 ----
-if [ "$SKIP_FRONTEND" = false ] && [ "$TARGET" != "miniapp" ]; then
-    info "构建管理后台前端 (admin-web)..."
-    (cd "$CODE_DIR/admin-web" && npm run build) || { error "admin-web 构建失败"; exit 1; }
+# ============================================================
+# 阶段 1: 停止服务 (释放内存给构建)
+# ============================================================
+stop_service() {
+    local module=$1
+    local pid=$(ps -ef | grep java | grep "$module" | grep -v grep | awk '{print $2}')
+
+    if [ -z "$pid" ]; then
+        info "$module 未在运行"
+        return 0
+    fi
+
+    for p in $pid; do
+        info "终止 $module (pid=$p)..."
+        kill "$p" 2>/dev/null
+
+        for i in $(seq 1 10); do
+            if ! kill -0 "$p" 2>/dev/null; then
+                info "进程 $p 已退出"
+                break
+            fi
+            sleep 1
+        done
 
-    info "构建 H5 前端 (admin-h5)..."
-    (cd "$CODE_DIR/admin-h5" && npm run build) || { error "admin-h5 构建失败"; exit 1; }
+        if kill -0 "$p" 2>/dev/null; then
+            warn "强制终止 $p"
+            kill -9 "$p" 2>/dev/null
+            sleep 1
+        fi
+    done
+}
+
+if [ "$NO_STOP" = false ]; then
+    case "$TARGET" in
+        admin)   stop_service "car-wash-admin" ;;
+        miniapp) stop_service "car-wash-miniapp" ;;
+        all)     stop_service "car-wash-admin"
+                 stop_service "car-wash-miniapp" ;;
+    esac
+    sleep 3
+fi
+
+# ============================================================
+# 阶段 2: 构建
+# ============================================================
 
-    info "前端构建完成"
+if [ "$SKIP_FRONTEND" = false ] && [ "$TARGET" != "miniapp" ]; then
+    for item in "admin-web:admin-web" "admin-h5:admin-h5"; do
+        dir="${item%%:*}"
+        name="${item##*:}"
+        info "构建前端 $name ..."
+        (
+            cd "$CODE_DIR/$dir" || exit 1
+            export NODE_OPTIONS="--max-old-space-size=$NODE_MAX_MEM"
+            low_prio npm run build
+        ) || { error "$name 构建失败"; exit 1; }
+        info "$name 构建完成"
+        sleep 2
+    done
+    info "前端构建全部完成"
 fi
 
-# ---- Maven 打包 ----
+export MAVEN_OPTS="-Xmx${MAVEN_XMX}m -Xms${MAVEN_XMS}m -XX:+UseSerialGC"
+
 if [ "$TARGET" = "miniapp" ]; then
     info "Maven 打包 (仅 miniapp)..."
-    (cd "$CODE_DIR" && mvn clean package -DskipTests -pl car-wash-miniapp -am) || { error "Maven 打包失败"; exit 1; }
+    (
+        cd "$CODE_DIR"
+        low_prio mvn clean package -DskipTests -pl car-wash-miniapp -am \
+            -T "${MAVEN_THREADS}" -Dmaven.test.skip=true
+    ) || { error "Maven 打包失败"; exit 1; }
 else
-    info "Maven 打包..."
-    (cd "$CODE_DIR" && mvn clean package -DskipTests) || { error "Maven 打包失败"; exit 1; }
+    info "Maven 打包 (全量, 线程=${MAVEN_THREADS})..."
+    (
+        cd "$CODE_DIR"
+        low_prio mvn clean package -DskipTests \
+            -T "${MAVEN_THREADS}" \
+            -Dmaven.test.skip=true \
+            -Dmaven.compiler.fork=false
+    ) || { error "Maven 打包失败"; exit 1; }
 fi
 
-# ---- 备份并复制 jar ----
+sleep 2
+
+# ============================================================
+# 阶段 3: 备份 & 部署 & 启动
+# ============================================================
+
 backup_and_copy() {
     local module=$1
     local jar_src="$CODE_DIR/$module/target/${module}-0.0.1-SNAPSHOT.jar"
@@ -76,45 +178,27 @@ backup_and_copy() {
     info "$module jar 已复制到 $APP_DIR"
 }
 
-# ---- 重启服务 (使用原版 wash-restart.sh 的 PID 检测逻辑) ----
-restart_service() {
+# 构建模块专用的 JVM 参数
+build_jvm_opts() {
     local module=$1
-    local jar_file="${module}-0.0.1-SNAPSHOT.jar"
-    local start_log="$LOG_DIR/${module}.log"
-
-    info "正在停止 $module ..."
-
-    # 用原版脚本的 grep 方式: grep java | grep 模块名
-    local pid=$(ps -ef | grep java | grep "$module" | grep -v grep | awk '{print $2}')
-
-    if [ -n "$pid" ]; then
-        # 多 pid 情况:逐个处理
-        for p in $pid; do
-            info "终止进程 $module (pid=$p)..."
-            kill "$p" 2>/dev/null
-
-            # 等待 10 秒
-            for i in $(seq 1 10); do
-                if ! kill -0 "$p" 2>/dev/null; then
-                    info "进程 $p 已退出"
-                    break
-                fi
-                sleep 1
-            done
-
-            # 没退出就强制 kill
-            if kill -0 "$p" 2>/dev/null; then
-                warn "强制终止 $p"
-                kill -9 "$p" 2>/dev/null
-                sleep 1
-            fi
-        done
+    if [ "$module" = "car-wash-admin" ]; then
+        echo "-Xmx${ADMIN_XMX}m -Xms${ADMIN_XMS}m -Xss${ADMIN_XSS}k \
+-XX:MaxMetaspaceSize=${ADMIN_META}m -XX:ReservedCodeCacheSize=${ADMIN_CODE_CACHE}m \
+-XX:+UseSerialGC -XX:+UseStringDeduplication"
     else
-        info "$module 未在运行"
+        echo "-Xmx${MINIAPP_XMX}m -Xms${MINIAPP_XMS}m -Xss${MINIAPP_XSS}k \
+-XX:MaxMetaspaceSize=${MINIAPP_META}m -XX:ReservedCodeCacheSize=${MINIAPP_CODE_CACHE}m \
+-XX:+UseSerialGC -XX:+UseStringDeduplication"
     fi
+}
+
+start_service() {
+    local module=$1
+    local jar_file="${module}-0.0.1-SNAPSHOT.jar"
+    local start_log="$LOG_DIR/${module}.log"
+    local jvm_opts=$(build_jvm_opts "$module")
 
-    # 确认端口释放
-    info "启动 $module ..."
+    info "启动 $module (JVM: $(echo $jvm_opts | tr -s ' '))..."
 
     local cert_arg=""
     if [ "$module" = "car-wash-admin" ]; then
@@ -122,7 +206,7 @@ restart_service() {
     fi
 
     cd "$APP_DIR"
-    nohup java -jar -Dspring.profiles.active=prod $cert_arg "$jar_file" > "$start_log" 2>&1 &
+    nohup java $jvm_opts -jar -Dspring.profiles.active=prod $cert_arg "$jar_file" > "$start_log" 2>&1 &
 
     sleep 5
     local new_pid=$(ps -ef | grep java | grep "$module" | grep -v grep | awk '{print $2}')
@@ -139,21 +223,20 @@ restart_service() {
     fi
 }
 
-# ---- 执行部署 ----
 case "$TARGET" in
     admin)
         backup_and_copy "car-wash-admin"
-        restart_service "car-wash-admin"
+        start_service "car-wash-admin"
         ;;
     miniapp)
         backup_and_copy "car-wash-miniapp"
-        restart_service "car-wash-miniapp"
+        start_service "car-wash-miniapp"
         ;;
     all)
         backup_and_copy "car-wash-admin"
         backup_and_copy "car-wash-miniapp"
-        restart_service "car-wash-admin"
-        restart_service "car-wash-miniapp"
+        start_service "car-wash-admin"
+        start_service "car-wash-miniapp"
         ;;
     *)
         error "未知模块: $TARGET (可选: admin | miniapp | all)"