#!/usr/bin/env bash # 配置部分 BASE_PATH=/root/ks DES_PATH=/root/ks JAR_PATH=${DES_PATH}/ruoyi-admin/target/ruoyi-admin.jar LOG_PATH=${DES_PATH}/logs LOG_FILE=${LOG_PATH}/backend.log BACK_LOG=${LOG_PATH}/back/backend-info.log MODEL_NAME=${JAR_PATH} PROFILE=dev # JVM配置 JVM_MEMORY=" -Xms2048M -Xmx2048M -XX:MaxDirectMemorySize=2048M" # 远程调试 JVM_DEBUG="" # JVM_DEBUG=" -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=6011" JVM_OPTION="${JVM_MEMORY} ${JVM_DEBUG}" _math() { printf "%s" "$(($@))" } # 输出绿色文字 __green() { printf '\33[1;32m%b\33[0m' "$1" "\n" } # 输出红色文字 __red() { printf '\33[1;31m%b\33[0m' "$1" "\n" } __kill() { local jar_path="$1" local sleep_seconds=10 local cur_sleep_second=1 local pids=() # 使用临时文件或直接遍历 jps 输出(避免进程替换) jps -l 2>/dev/null | while read -r pid main_class; do if [ "$main_class" = "$jar_path" ]; then echo "$pid" fi done > /tmp/ruoyi_pids.$$ # 读取匹配的 PID 到数组(在当前 shell 中) while IFS= read -r pid; do [ -n "$pid" ] && pids+=("$pid") done < /tmp/ruoyi_pids.$$ # 清理临时文件 rm -f /tmp/ruoyi_pids.$$ if [ ${#pids[@]} -eq 0 ]; then __green "未找到运行中的进程: $jar_path" return 0 fi __green "找到 ${#pids[@]} 个匹配进程: ${pids[*]}" # 发送 SIGTERM for pid in "${pids[@]}"; do __green "发送 SIGTERM 到 PID: $pid" kill "$pid" >/dev/null 2>&1 done # 等待退出 while [ $cur_sleep_second -le $sleep_seconds ]; do remaining=() for pid in "${pids[@]}"; do if kill -0 "$pid" 2>/dev/null; then remaining+=("$pid") fi done if [ ${#remaining[@]} -eq 0 ]; then __green "所有进程已成功停止" return 0 fi __green "等待进程退出... (${cur_sleep_second}/${sleep_seconds} 秒)" sleep 1 cur_sleep_second=$((cur_sleep_second + 1)) done # 强制 kill -9 __red "优雅关闭超时,强制终止剩余进程: ${remaining[*]}" for pid in "${remaining[@]}"; do kill -9 "$pid" 2>/dev/null done # 检查是否还有存活 still_alive=() for pid in "${remaining[@]}"; do if kill -0 "$pid" 2>/dev/null; then still_alive+=("$pid") fi done if [ ${#still_alive[@]} -gt 0 ]; then __red "无法终止进程: ${still_alive[*]}" return 1 else __green "所有进程已强制终止" return 0 fi } # 获取本机IP __get_ip() { local ip=$(ifconfig | grep "10.0.0" | awk '{print $2}' | cut -d ':' -f 2 | head -n 1) if [[ -z "$ip" ]]; then ip=$(ifconfig -a | grep -E '172.|10.|192.' | grep -E 'Bcast|broadcast' | grep -E 'Mask|netmask' | awk '{print $2}' | cut -d ':' -f 2 | head -n 1) fi echo "$ip" } # 创建日志目录 __create_log_dir() { if [[ ! -d "$LOG_PATH" ]]; then mkdir -p "$LOG_PATH" __green "创建日志目录: $LOG_PATH" fi if [[ ! -d "$(dirname "$BACK_LOG")" ]]; then mkdir -p "$(dirname "$BACK_LOG")" __green "创建备份日志目录: $(dirname "$BACK_LOG")" fi } # 主函数 main() { # 加载环境变量 source /etc/profile # 获取最新代码 __green "拉取最新代码..." git --git-dir=${BASE_PATH}/.git --work-tree=${BASE_PATH} fetch origin main git --git-dir=${BASE_PATH}/.git --work-tree=${BASE_PATH} reset --hard origin/main git --git-dir=${BASE_PATH}/.git --work-tree=${BASE_PATH} pull origin main # 构建项目 __green "开始构建项目..." cd ${BASE_PATH} && mvn clean && mvn install -T 4 if [[ $? -ne 0 ]]; then __red "Maven构建失败!" exit 1 fi # 检查JAR文件是否存在 if [[ ! -f "$JAR_PATH" ]]; then __red "JAR文件不存在: $JAR_PATH" exit 1 fi # 停止现有进程 __green "停止现有进程..." __kill "$MODEL_NAME" # 创建日志目录 __create_log_dir # 获取本机IP SELF_IP=$(__get_ip) __green "本机IP: $SELF_IP" # 启动应用 __green "启动应用..." nohup java ${JVM_OPTION} -jar ${JAR_PATH} --spring.profiles.active=${PROFILE} >> ${LOG_FILE} 2>&1 & tail -f logs/backend.log # 等待应用启动 sleep 3 # 检查进程是否启动成功 local new_pid=$(ps -ef | grep "${MODEL_NAME}.jar" | grep -v grep | awk '{print $2}') if [[ -n "$new_pid" ]]; then __green "应用启动成功! PID: $new_pid" else __red "应用启动失败!" exit 1 fi # 跟踪日志 __green "开始跟踪日志..." tail -f ${LOG_FILE} } # 执行主函数 main "$@"