瀏覽代碼

feat: 添加本地同步部署脚本 sync-and-deploy.sh

何文松 1 月之前
父節點
當前提交
273b8f9842
共有 1 個文件被更改,包括 289 次插入0 次删除
  1. 289 0
      sync-and-deploy.sh

+ 289 - 0
sync-and-deploy.sh

@@ -0,0 +1,289 @@
+#!/bin/bash
+
+# ============================================
+# 灵越智报 - 同步代码并部署脚本
+# 从本地同步代码到服务器并重启应用
+# ============================================
+
+set -e
+
+# 颜色定义
+RED='\033[0;31m'
+GREEN='\033[0;32m'
+YELLOW='\033[1;33m'
+BLUE='\033[0;34m'
+NC='\033[0m'
+
+# ========== 配置区域 ==========
+# 服务器配置(根据实际情况修改)
+SERVER_USER="root"
+SERVER_HOST="${SERVER_HOST:-lanaipc}"  # 可通过环境变量覆盖,或直接改为 IP
+SERVER_PORT="${SERVER_PORT:-22}"
+
+# 路径配置
+LOCAL_PROJECT_DIR="/home/hws/workspace/GitLab/ay/lingyue-zhibao"
+REMOTE_PROJECT_DIR="/mnt/win_home/lingyue-zhibao"
+REMOTE_MAVEN_REPO="/mnt/win_home/.m2/repository"
+
+# 应用配置
+APP_PORT=5232
+JAR_NAME="lingyue-starter.jar"
+# ==============================
+
+log_info() { echo -e "${GREEN}[INFO]${NC} $1"; }
+log_warn() { echo -e "${YELLOW}[WARN]${NC} $1"; }
+log_error() { echo -e "${RED}[ERROR]${NC} $1"; }
+log_title() { echo -e "\n${BLUE}========== $1 ==========${NC}\n"; }
+
+# SSH 命令封装
+ssh_cmd() {
+    ssh -p ${SERVER_PORT} ${SERVER_USER}@${SERVER_HOST} "$@"
+}
+
+# 检查服务器连接
+check_connection() {
+    log_title "检查服务器连接"
+    
+    if ssh_cmd "echo 'OK'" > /dev/null 2>&1; then
+        log_info "服务器连接成功: ${SERVER_USER}@${SERVER_HOST}"
+    else
+        log_error "无法连接服务器: ${SERVER_USER}@${SERVER_HOST}"
+        log_warn "请检查:"
+        log_warn "  1. 服务器地址是否正确"
+        log_warn "  2. SSH 密钥是否配置"
+        log_warn "  3. 可以通过 SERVER_HOST=<IP> ./sync-and-deploy.sh 指定服务器"
+        exit 1
+    fi
+}
+
+# 同步代码
+sync_code() {
+    log_title "同步代码到服务器"
+    
+    cd ${LOCAL_PROJECT_DIR}
+    
+    log_info "正在同步..."
+    rsync -avz --delete \
+        --exclude '.git' \
+        --exclude 'target' \
+        --exclude 'node_modules' \
+        --exclude '.idea' \
+        --exclude '*.iml' \
+        --exclude '.DS_Store' \
+        --exclude 'frontend_flutter/build' \
+        --exclude 'frontend_flutter/.dart_tool' \
+        -e "ssh -p ${SERVER_PORT}" \
+        ./ ${SERVER_USER}@${SERVER_HOST}:${REMOTE_PROJECT_DIR}/
+    
+    log_info "代码同步完成"
+}
+
+# 停止应用
+stop_app() {
+    log_title "停止应用"
+    
+    ssh_cmd "pkill -f '${JAR_NAME}' 2>/dev/null || true"
+    sleep 2
+    
+    # 确保进程已停止
+    if ssh_cmd "pgrep -f '${JAR_NAME}'" > /dev/null 2>&1; then
+        log_warn "进程仍在运行,强制终止..."
+        ssh_cmd "pkill -9 -f '${JAR_NAME}' 2>/dev/null || true"
+        sleep 2
+    fi
+    
+    log_info "应用已停止"
+}
+
+# 编译项目
+build_project() {
+    log_title "编译项目"
+    
+    ssh_cmd "cd ${REMOTE_PROJECT_DIR}/backend && \
+             rm -rf lingyue-starter/target && \
+             mvn clean package -DskipTests -q -Dmaven.repo.local=${REMOTE_MAVEN_REPO}"
+    
+    log_info "编译完成"
+}
+
+# 启动应用
+start_app() {
+    log_title "启动应用"
+    
+    ssh_cmd "cd ${REMOTE_PROJECT_DIR}/backend && \
+             nohup java -Xms1g -Xmx2g -XX:+UseG1GC \
+                   -jar lingyue-starter/target/${JAR_NAME} \
+                   > /var/log/lingyue.log 2>&1 &"
+    
+    log_info "应用启动中..."
+    sleep 5
+    
+    # 检查应用是否启动
+    if ssh_cmd "pgrep -f '${JAR_NAME}'" > /dev/null 2>&1; then
+        log_info "应用启动成功"
+    else
+        log_error "应用启动失败,查看日志:"
+        ssh_cmd "tail -50 /var/log/lingyue.log"
+        exit 1
+    fi
+}
+
+# 健康检查
+health_check() {
+    log_title "健康检查"
+    
+    local max_attempts=10
+    local attempt=1
+    
+    while [ $attempt -le $max_attempts ]; do
+        log_info "尝试 $attempt/$max_attempts..."
+        
+        local response=$(ssh_cmd "curl -s -o /dev/null -w '%{http_code}' http://localhost:${APP_PORT}/actuator/health 2>/dev/null" || echo "000")
+        
+        if [ "$response" = "200" ]; then
+            log_info "健康检查通过 ✓"
+            ssh_cmd "curl -s http://localhost:${APP_PORT}/actuator/health"
+            echo ""
+            return 0
+        fi
+        
+        sleep 3
+        attempt=$((attempt + 1))
+    done
+    
+    log_warn "健康检查超时,但应用可能仍在启动中"
+    log_info "可以手动检查: curl http://${SERVER_HOST}:${APP_PORT}/actuator/health"
+}
+
+# 查看日志
+show_logs() {
+    log_title "应用日志"
+    ssh_cmd "tail -100 /var/log/lingyue.log"
+}
+
+# 查看实时日志
+tail_logs() {
+    log_info "实时日志 (Ctrl+C 退出)"
+    ssh_cmd "tail -f /var/log/lingyue.log"
+}
+
+# 查看状态
+show_status() {
+    log_title "应用状态"
+    
+    if ssh_cmd "pgrep -f '${JAR_NAME}'" > /dev/null 2>&1; then
+        local pid=$(ssh_cmd "pgrep -f '${JAR_NAME}'")
+        log_info "应用运行中 (PID: $pid)"
+        log_info "访问地址: http://${SERVER_HOST}:${APP_PORT}"
+    else
+        log_warn "应用未运行"
+    fi
+}
+
+# 仅同步代码(不编译不重启)
+sync_only() {
+    check_connection
+    sync_code
+    log_info "代码同步完成,未编译和重启"
+}
+
+# 完整部署
+full_deploy() {
+    check_connection
+    sync_code
+    stop_app
+    build_project
+    start_app
+    health_check
+    
+    log_title "部署完成"
+    echo -e "${GREEN}访问地址: http://${SERVER_HOST}:${APP_PORT}${NC}"
+    echo ""
+    echo "测试命令:"
+    echo "  curl http://${SERVER_HOST}:${APP_PORT}/actuator/health"
+    echo "  curl -X POST http://${SERVER_HOST}:${APP_PORT}/auth/register -H 'Content-Type: application/json' -d '{\"username\":\"test\",\"email\":\"test@test.com\",\"password\":\"123456\"}'"
+}
+
+# 快速重启(不同步代码)
+quick_restart() {
+    check_connection
+    stop_app
+    start_app
+    health_check
+}
+
+# 显示帮助
+show_help() {
+    cat <<EOF
+灵越智报 - 同步代码并部署脚本
+
+用法: ./sync-and-deploy.sh [命令]
+
+命令:
+    deploy          完整部署(同步 + 编译 + 重启)
+    sync            仅同步代码(不编译不重启)
+    restart         快速重启(不同步代码)
+    stop            停止应用
+    status          查看应用状态
+    logs            查看最近日志
+    tail            实时查看日志
+    build           远程编译(不重启)
+    help            显示此帮助
+
+环境变量:
+    SERVER_HOST     服务器地址(默认: lanaipc)
+    SERVER_PORT     SSH 端口(默认: 22)
+
+示例:
+    ./sync-and-deploy.sh deploy                    # 完整部署
+    ./sync-and-deploy.sh sync                      # 仅同步
+    ./sync-and-deploy.sh restart                   # 快速重启
+    SERVER_HOST=192.168.1.100 ./sync-and-deploy.sh deploy  # 指定服务器
+
+EOF
+}
+
+# 主函数
+main() {
+    case "${1:-deploy}" in
+        deploy)
+            full_deploy
+            ;;
+        sync)
+            sync_only
+            ;;
+        restart)
+            quick_restart
+            ;;
+        stop)
+            check_connection
+            stop_app
+            ;;
+        status)
+            check_connection
+            show_status
+            ;;
+        logs)
+            check_connection
+            show_logs
+            ;;
+        tail)
+            check_connection
+            tail_logs
+            ;;
+        build)
+            check_connection
+            build_project
+            ;;
+        help|--help|-h)
+            show_help
+            ;;
+        *)
+            log_error "未知命令: $1"
+            show_help
+            exit 1
+            ;;
+    esac
+}
+
+main "$@"