diff --git a/app/run.sh b/app/run.sh new file mode 100644 index 0000000..d601ca0 --- /dev/null +++ b/app/run.sh @@ -0,0 +1,293 @@ +#!/bin/bash + +# ============================================== +# Java应用管理脚本 v2.0 +# 功能:启动/停止/重启/状态检查/日志查看/升级/备份 +# ============================================== + +# -------------------------- +# 配置区(请根据实际情况修改) +# -------------------------- +APP_NAME="snailjob-server" # 应用名称 +APP_DIR="../lib" # 应用目录(支持绝对路径) +JAR_NAME="ruoyi-snailjob-server.jar" # JAR文件名 +JAVA_OPTS="-Xms256m -Xmx512m -XX:+UseG1GC -Dfile.encoding=UTF-8" # JVM参数 +LOG_FILE="${APP_DIR}/app.log" # 日志文件路径 +PID_FILE="${APP_DIR}/app.pid" # PID文件路径 +MAX_LOG_SIZE=10 # 日志轮转大小(MB) +BACKUP_DIR="${APP_DIR}/backup" # 备份目录 +WAIT_STOP_TIMEOUT=30 # 停止等待超时(秒) + +# -------------------------- +# 初始化检查 +# -------------------------- +init_check() { + # 检查Java环境 + if ! command -v java &> /dev/null; then + echo "[ERROR] Java未安装!请先安装JDK" + exit 1 + fi + + # 检查目录是否存在 + if [ ! -d "$APP_DIR" ]; then + echo "[ERROR] 应用目录不存在: $APP_DIR" + exit 1 + fi + + # 检查JAR文件是否存在 + if [ ! -f "${APP_DIR}/${JAR_NAME}" ]; then + echo "[ERROR] JAR文件不存在: ${APP_DIR}/${JAR_NAME}" + exit 1 + fi + + # 创建备份目录 + mkdir -p "$BACKUP_DIR" +} + +# -------------------------- +# 日志轮转 +# -------------------------- +rotate_log() { + if [ -f "$LOG_FILE" ]; then + log_size=$(du -m "$LOG_FILE" | cut -f1) + if [ "$log_size" -gt "$MAX_LOG_SIZE" ]; then + echo "正在轮转日志文件..." + timestamp=$(date +%Y%m%d%H%M%S) + mv "$LOG_FILE" "${LOG_FILE}.$timestamp" + gzip "${LOG_FILE}.$timestamp" -f + mv "${LOG_FILE}.$timestamp.gz" "$BACKUP_DIR/" + touch "$LOG_FILE" + fi + fi +} + +# -------------------------- +# 获取应用状态 +# -------------------------- +status() { + if [ -f "$PID_FILE" ]; then + pid=$(cat "$PID_FILE") + if ps -p "$pid" > /dev/null; then + echo "[INFO] $APP_NAME 正在运行 (PID: $pid)" + return 0 + else + echo "[WARN] PID文件存在但进程未运行,可能存在异常退出" + return 1 + fi + else + echo "[INFO] $APP_NAME 未运行" + return 3 + fi +} + +# -------------------------- +# 启动应用 +# -------------------------- +start() { + init_check + status >/dev/null 2>&1 + local running=$? + + if [ $running -eq 0 ]; then + echo "[WARN] $APP_NAME 已经在运行中 (PID: $(cat "$PID_FILE"))" + return 1 + fi + + # 清理无效PID文件 + if [ $running -eq 1 ]; then + rm -f "$PID_FILE" + fi + + rotate_log + + echo "正在启动 $APP_NAME..." + cd "$APP_DIR" || exit 1 + + # 使用exec启动以便获取正确的PID + nohup java $JAVA_OPTS -jar "$JAR_NAME" >> "$LOG_FILE" 2>&1 & + local pid=$! + + echo $pid > "$PID_FILE" + echo "[SUCCESS] $APP_NAME 已启动 (PID: $pid)" + echo "日志文件: $LOG_FILE" +} + +# -------------------------- +# 停止应用 +# -------------------------- +stop() { + status >/dev/null 2>&1 + local running=$? + + if [ $running -ne 0 ]; then + echo "[WARN] $APP_NAME 未运行" + return 1 + fi + + local pid=$(cat "$PID_FILE") + echo "正在停止 $APP_NAME (PID: $pid)..." + + # 先尝试优雅关闭 + kill $pid + + # 等待进程退出 + local count=0 + while [ $count -lt $WAIT_STOP_TIMEOUT ]; do + if ! ps -p $pid > /dev/null; then + break + fi + sleep 1 + ((count++)) + done + + # 强制终止 + if ps -p $pid > /dev/null; then + echo "[WARN] 优雅关闭失败,尝试强制终止..." + kill -9 $pid + sleep 1 + fi + + rm -f "$PID_FILE" + echo "[SUCCESS] $APP_NAME 已停止" +} + +# -------------------------- +# 重启应用 +# -------------------------- +restart() { + stop + sleep 2 + start +} + +# -------------------------- +# 查看日志 +# -------------------------- +tail_log() { + if [ ! -f "$LOG_FILE" ]; then + echo "[ERROR] 日志文件不存在: $LOG_FILE" + return 1 + fi + + echo "正在显示日志: $LOG_FILE (Ctrl+C 退出)" + echo "--------------------------------------------------" + tail -f "$LOG_FILE" +} + +# -------------------------- +# 备份应用 +# -------------------------- +backup() { + local timestamp=$(date +%Y%m%d%H%M%S) + local backup_file="${BACKUP_DIR}/${JAR_NAME%.*}_${timestamp}.jar" + + echo "正在备份应用到: $backup_file" + cp "${APP_DIR}/${JAR_NAME}" "$backup_file" + + if [ $? -eq 0 ]; then + echo "[SUCCESS] 备份完成" + return 0 + else + echo "[ERROR] 备份失败" + return 1 + fi +} + +# -------------------------- +# 升级应用 +# -------------------------- +upgrade() { + local new_jar="$JAR_NAME" + local lib_dir="$APP_DIR" + local backup_dir="${BACKUP_DIR}/lib" + + # 检查新的JAR文件是否存在 + if [ ! -f "$new_jar" ]; then + echo "[ERROR] 新的JAR文件不存在: $new_jar" + return 1 + fi + + # 检查lib目录是否存在 + if [ ! -d "$lib_dir" ]; then + echo "[ERROR] lib目录不存在: $lib_dir" + return 1 + fi + + # 检查backup目录是否存在,不存在则创建 + mkdir -p "$backup_dir" + + # 获取lib目录下原有的JAR文件名 + local old_jar=$(ls "$lib_dir" | grep -E "^${JAR_NAME%.jar}-[0-9]{14}\.jar$") + if [ -z "$old_jar" ]; then + old_jar="$JAR_NAME" + fi + + # 备份原有的JAR文件 + local timestamp=$(date +%Y%m%d%H%M%S) + local backup_file="${backup_dir}/${old_jar%.jar}_${timestamp}.jar" + cp "${lib_dir}/${old_jar}" "$backup_file" + if [ $? -eq 0 ]; then + echo "[SUCCESS] 备份原有JAR文件到: $backup_file" + else + echo "[ERROR] 备份原有JAR文件失败" + return 1 + fi + + # 复制新的JAR文件到lib目录 + cp "$new_jar" "$lib_dir/" + if [ $? -eq 0 ]; then + echo "[SUCCESS] 升级JAR文件到: $lib_dir/$new_jar" + else + echo "[ERROR] 升级JAR文件失败" + return 1 + fi + + # 删除旧的JAR文件(可选,如果保留旧版本则不需要删除) + # rm -f "${lib_dir}/${old_jar}" + # if [ $? -eq 0 ]; then + # echo "[SUCCESS] 删除旧的JAR文件: ${lib_dir}/${old_jar}" + # else + # echo "[ERROR] 删除旧的JAR文件失败" + # return 1 + # fi +} + +# -------------------------- +# 主程序 +# -------------------------- +case "$1" in + start) + start + ;; + stop) + stop + ;; + restart) + restart + ;; + status) + status + ;; + log) + tail_log + ;; + backup) + backup + ;; + upgrade) + upgrade + ;; + *) + echo "用法: $0 {start|stop|restart|status|log|backup|upgrade}" + echo " start 启动应用" + echo " stop 停止应用" + echo " restart 重启应用" + echo " status 查看状态" + echo " log 查看实时日志" + echo " backup 备份应用" + echo " upgrade 升级应用" + exit 1 + ;; +esac + +exit 0