294 lines
7.1 KiB
Bash
294 lines
7.1 KiB
Bash
#!/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
|