#!/bin/bash # ============================================ # 全量部署脚本 - 前后端一起部署 # 用法: bash deploy-all.sh [backend-only|frontend-only] # ============================================ set -e DATE=$(date +%Y%m%d%H%M) # ==================== 配置区 ==================== # 项目路径 PROJECT_DIR=/www/wwwroot/sionrui # 后端配置 BACKEND_DIR=/www/wwwroot/yudao-server BACKEND_JAR_NAME=yudao-server.jar BACKEND_PORT=9900 # 前端配置 FRONTEND_SRC=$PROJECT_DIR/frontend/app/web-gold/dist FRONTEND_DIR=/www/wwwroot/muyetools.cn # JVM 参数 JAVA_OPTS="-Xms1g -Xmx1g -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=$BACKEND_DIR/heapError" # 环境 PROFILES_ACTIVE=prod # 健康检查 URL HEALTH_CHECK_URL=http://127.0.0.1:$BACKEND_PORT/actuator/health/ # ==================== 函数定义 ==================== log() { echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" } # 后端备份 backup_backend() { if [ -f "$BACKEND_DIR/$BACKEND_JAR_NAME" ]; then log "[后端] 备份旧 JAR 包..." mkdir -p $BACKEND_DIR/backup cp $BACKEND_DIR/$BACKEND_JAR_NAME $BACKEND_DIR/backup/yudao-server-$DATE.jar # 只保留最近 5 个备份 cd $BACKEND_DIR/backup && ls -t | tail -n +6 | xargs -r rm -f fi } # 停止后端服务 stop_backend() { log "[后端] 停止服务..." PID=$(ps -ef | grep $BACKEND_DIR/$BACKEND_JAR_NAME | grep -v "grep" | awk '{print $2}') if [ -n "$PID" ]; then log "[后端] 发现进程 PID: $PID,正在停止..." kill -15 $PID # 等待最多 60 秒 for i in {1..60}; do sleep 1 PID=$(ps -ef | grep $BACKEND_DIR/$BACKEND_JAR_NAME | grep -v "grep" | awk '{print $2}') if [ -z "$PID" ]; then log "[后端] 服务已停止" return 0 fi echo -n "." done # 强制杀死 log "[后端] 强制停止..." kill -9 $PID 2>/dev/null || true else log "[后端] 服务未运行" fi } # 启动后端服务 start_backend() { log "[后端] 启动服务..." log "[后端] JAVA_OPTS: $JAVA_OPTS" log "[后端] PROFILES: $PROFILES_ACTIVE" cd $BACKEND_DIR mkdir -p $BACKEND_DIR/logs mkdir -p $BACKEND_DIR/heapError nohup java -server $JAVA_OPTS -jar $BACKEND_JAR_NAME --spring.profiles.active=$PROFILES_ACTIVE > $BACKEND_DIR/logs/console.log 2>&1 & log "[后端] 服务启动中..." } # 后端健康检查 health_check() { if [ -n "$HEALTH_CHECK_URL" ]; then log "[后端] 健康检查开始..." for i in {1..120}; do sleep 1 result=$(curl -s -o /dev/null -w "%{http_code}" $HEALTH_CHECK_URL 2>/dev/null || echo "000") if [ "$result" == "200" ]; then log "[后端] 健康检查通过!" return 0 fi echo -n "." done log "[后端] 健康检查失败,查看日志:" tail -n 20 $BACKEND_DIR/logs/console.log return 1 fi } # 部署后端 deploy_backend() { log "========== 开始部署后端 ==========" # 拉取代码 log "[后端] 拉取最新代码..." cd $PROJECT_DIR git fetch origin git reset --hard origin/main # 构建(只构建 yudao-server 模块) log "[后端] 构建 JAR 包..." mvn clean package -DskipTests -pl yudao-server -am -q # 备份 backup_backend # 复制新 JAR log "[后端] 复制 JAR 包..." cp $PROJECT_DIR/yudao-server/target/yudao-server.jar $BACKEND_DIR/ # 停止旧服务 stop_backend # 启动新服务 start_backend # 健康检查 health_check log "========== 后端部署完成 ==========" } # 部署前端 deploy_frontend() { log "========== 开始部署前端 ==========" cd $PROJECT_DIR/frontend # 安装依赖 log "[前端] 安装依赖..." pnpm install # 构建 log "[前端] 构建项目..." pnpm build # 备份旧文件 if [ -d "$FRONTEND_DIR" ] && [ "$(ls -A $FRONTEND_DIR 2>/dev/null)" ]; then log "[前端] 备份旧文件..." mkdir -p /www/wwwroot/web-gold-backup rm -rf /www/wwwroot/web-gold-backup/dist-$DATE cp -r $FRONTEND_DIR /www/wwwroot/web-gold-backup/dist-$DATE fi # 部署新文件 log "[前端] 部署新文件..." rm -rf $FRONTEND_DIR/* cp -r $FRONTEND_SRC/* $FRONTEND_DIR/ log "========== 前端部署完成 ==========" } # ==================== 主流程 ==================== main() { log "==========================================" log "开始部署: $(date '+%Y-%m-%d %H:%M:%S')" log "==========================================" case "$1" in backend-only) deploy_backend ;; frontend-only) deploy_frontend ;; *) deploy_backend deploy_frontend ;; esac log "==========================================" log "全部部署完成: $(date '+%Y-%m-%d %H:%M:%S')" log "==========================================" } main "$@"