Преглед на файлове

refactor: 洗车部署脚本改造为智能柜项目 + 适配4C8G服务器

- 项目名/模块名/前端名全部替换为haha系
- 移除微信支付证书参数
- JVM内存翻倍适配4核8G
- SerialGC升级为G1GC
- Maven线程从1增到2

Co-Authored-By: Claude <noreply@anthropic.com>
skyline преди 1 ден
родител
ревизия
8205d7baee
променени са 1 файла, в които са добавени 239 реда и са изтрити 0 реда
  1. 239 0
      deploy.sh

+ 239 - 0
deploy.sh

@@ -0,0 +1,239 @@
+#!/bin/bash
+
+# ============================================================
+# 智能柜项目一键部署脚本 (4核8G 服务器优化版)
+# 用法: ./deploy.sh [admin|miniapp|all] [--skip-frontend] [--no-stop]
+#       --no-stop  构建前不停止服务 (零停机,JVM 已限制内存)
+# 调试: bash -x ./deploy.sh
+# ============================================================
+
+APP_DIR="/data/app"
+CODE_DIR="/data/code/haha"
+BACKUP_DIR="/data/backup"
+LOG_DIR="/data/logs"
+HISTORY_FILE="/data/history"
+
+RED='\033[0;31m'
+GREEN='\033[0;32m'
+YELLOW='\033[1;33m'
+NC='\033[0m'
+
+log()   { echo -e "[$(date '+%H:%M:%S')] $1"; }
+info()  { log "${GREEN}INFO${NC}  $1"; }
+warn()  { log "${YELLOW}WARN${NC}  $1"; }
+error() { log "${RED}ERROR${NC} $1"; }
+
+mkdir -p "$LOG_DIR" "$BACKUP_DIR"
+
+# ============================================================
+# 资源限制配置 (4核8G 服务器)
+# ============================================================
+
+# ---- 构建阶段 ----
+NODE_MAX_MEM="${NODE_MAX_MEM:-2048}"      # Node 最大 old-space MB
+MAVEN_XMX="${MAVEN_XMX:-1024}"            # Maven JVM 最大堆 MB
+MAVEN_XMS="${MAVEN_XMS:-256}"             # Maven JVM 初始堆 MB
+MAVEN_THREADS="${MAVEN_THREADS:-2}"       # Maven 编译线程数
+
+# ---- 运行时 JVM (admin 模块) ----
+ADMIN_XMX="${ADMIN_XMX:-1536}"            # 最大堆 MB
+ADMIN_XMS="${ADMIN_XMS:-256}"             # 初始堆 MB
+ADMIN_META="${ADMIN_META:-256}"           # 元空间上限 MB
+ADMIN_CODE_CACHE="${ADMIN_CODE_CACHE:-128}" # JIT 代码缓存 MB
+ADMIN_XSS="${ADMIN_XSS:-256}"             # 线程栈 KB
+
+# ---- 运行时 JVM (miniapp 模块) ----
+MINIAPP_XMX="${MINIAPP_XMX:-1024}"
+MINIAPP_XMS="${MINIAPP_XMS:-256}"
+MINIAPP_META="${MINIAPP_META:-256}"
+MINIAPP_CODE_CACHE="${MINIAPP_CODE_CACHE:-128}"
+MINIAPP_XSS="${MINIAPP_XSS:-256}"
+
+# 低优先级包装器
+low_prio() {
+    nice -n 19 ionice -c 2 -n 7 "$@"
+}
+
+# ---- 参数解析 ----
+TARGET="${1:-all}"
+SKIP_FRONTEND=false
+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; }
+low_prio git pull origin master || { error "git pull 失败"; 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
+
+        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 "haha-admin" ;;
+        miniapp) stop_service "haha-miniapp" ;;
+        all)     stop_service "haha-admin"
+                 stop_service "haha-miniapp" ;;
+    esac
+    sleep 3
+fi
+
+# ============================================================
+# 阶段 2: 构建
+# ============================================================
+
+if [ "$SKIP_FRONTEND" = false ] && [ "$TARGET" != "miniapp" ]; then
+    info "构建前端 admin-web ..."
+    (
+        cd "$CODE_DIR/haha-admin-web" || exit 1
+        export NODE_OPTIONS="--max-old-space-size=$NODE_MAX_MEM"
+        low_prio npm run build
+    ) || { error "admin-web 构建失败"; exit 1; }
+    info "admin-web 构建完成"
+    sleep 2
+fi
+
+export MAVEN_OPTS="-Xmx${MAVEN_XMX}m -Xms${MAVEN_XMS}m -XX:+UseSerialGC"
+
+if [ "$TARGET" = "miniapp" ]; then
+    info "Maven 打包 (仅 miniapp)..."
+    (
+        cd "$CODE_DIR"
+        low_prio mvn clean package -DskipTests -pl haha-miniapp -am \
+            -T "${MAVEN_THREADS}" -Dmaven.test.skip=true
+    ) || { error "Maven 打包失败"; exit 1; }
+else
+    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
+
+sleep 2
+
+# ============================================================
+# 阶段 3: 备份 & 部署 & 启动
+# ============================================================
+
+backup_and_copy() {
+    local module=$1
+    local jar_src="$CODE_DIR/$module/target/${module}-0.0.1-SNAPSHOT.jar"
+    local jar_dst="$APP_DIR/${module}-0.0.1-SNAPSHOT.jar"
+
+    if [ ! -f "$jar_src" ]; then
+        error "未找到 jar 文件: $jar_src"
+        exit 1
+    fi
+
+    if [ -f "$jar_dst" ]; then
+        cp "$jar_dst" "$BACKUP_DIR/${module}-0.0.1-SNAPSHOT.jar.$(date +%Y%m%d_%H%M%S)"
+        info "已备份 $module (保留最近 5 个)"
+        ls -t "$BACKUP_DIR/${module}"-*.jar 2>/dev/null | tail -n +6 | xargs -r rm -f
+    fi
+    cp "$jar_src" "$jar_dst"
+    info "$module jar 已复制到 $APP_DIR"
+}
+
+# 构建模块专用的 JVM 参数
+build_jvm_opts() {
+    local module=$1
+    if [ "$module" = "haha-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:+UseG1GC -XX:MaxGCPauseMillis=200"
+    else
+        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:+UseG1GC -XX:MaxGCPauseMillis=200"
+    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 (JVM: $(echo $jvm_opts | tr -s ' '))..."
+
+    cd "$APP_DIR"
+    nohup java $jvm_opts -jar -Dspring.profiles.active=prod "$jar_file" > "$start_log" 2>&1 &
+
+    sleep 5
+    local new_pid=$(ps -ef | grep java | grep "$module" | grep -v grep | awk '{print $2}')
+
+    if [ -n "$new_pid" ]; then
+        info "$module 启动成功 (pid=$new_pid)"
+        echo "$(date) $module restarted" >> "$HISTORY_FILE"
+    else
+        error "$module 可能启动失败,查看日志:"
+        echo "--- $start_log ---"
+        tail -30 "$start_log"
+        echo "--- end ---"
+        exit 1
+    fi
+}
+
+case "$TARGET" in
+    admin)
+        backup_and_copy "haha-admin"
+        start_service "haha-admin"
+        ;;
+    miniapp)
+        backup_and_copy "haha-miniapp"
+        start_service "haha-miniapp"
+        ;;
+    all)
+        backup_and_copy "haha-admin"
+        backup_and_copy "haha-miniapp"
+        start_service "haha-admin"
+        start_service "haha-miniapp"
+        ;;
+    *)
+        error "未知模块: $TARGET (可选: admin | miniapp | all)"
+        exit 1
+        ;;
+esac
+
+echo "========================================"
+info "部署完成"
+echo "========================================"