155 lines
3.9 KiB
Bash
155 lines
3.9 KiB
Bash
#!/usr/bin/env bash
|
||
set -Eeuo pipefail
|
||
|
||
# 将 deploy.sh 和 bms-admin.jar 放在应用目录中,然后执行:
|
||
# bash deploy.sh start|stop|restart|status
|
||
# 服务使用当前执行用户运行,控制台输出追加到 logs/console.log。
|
||
|
||
APP_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd -P)"
|
||
JAR_NAME="bms-admin.jar"
|
||
JAR_PATH="$APP_DIR/$JAR_NAME"
|
||
LOG_DIR="$APP_DIR/logs"
|
||
CONSOLE_LOG="$LOG_DIR/console.log"
|
||
JAVA_BIN="/www/server/java/jdk-17.0.8/bin/java"
|
||
|
||
usage() {
|
||
echo "用法:bash deploy.sh {start|stop|restart|status}"
|
||
}
|
||
|
||
# 精确匹配由本目录启动的 bms-admin.jar,避免误停 ES 或其他 Java 服务。
|
||
find_app_pids() {
|
||
local pid arg jar_arg cwd i
|
||
local -a args
|
||
|
||
while read -r pid; do
|
||
[[ -r "/proc/$pid/cmdline" ]] || continue
|
||
args=()
|
||
while IFS= read -r -d '' arg; do
|
||
args+=("$arg")
|
||
done < "/proc/$pid/cmdline"
|
||
|
||
jar_arg=""
|
||
for ((i = 1; i + 1 < ${#args[@]}; i++)); do
|
||
if [[ "${args[i]}" == "-jar" ]]; then
|
||
jar_arg="${args[i + 1]}"
|
||
break
|
||
fi
|
||
done
|
||
|
||
case "$jar_arg" in
|
||
"$JAR_PATH")
|
||
echo "$pid"
|
||
;;
|
||
"$JAR_NAME"|"./$JAR_NAME")
|
||
cwd="$(readlink -f "/proc/$pid/cwd" 2>/dev/null || true)"
|
||
[[ "$cwd" == "$APP_DIR" ]] && echo "$pid" || true
|
||
;;
|
||
esac
|
||
done < <(pgrep -x java || true)
|
||
}
|
||
|
||
resolve_java() {
|
||
if [[ ! -x "$JAVA_BIN" ]]; then
|
||
JAVA_BIN="$(command -v java || true)"
|
||
fi
|
||
if [[ -z "$JAVA_BIN" || ! -x "$JAVA_BIN" ]]; then
|
||
echo "错误:找不到 Java。"
|
||
return 1
|
||
fi
|
||
}
|
||
|
||
start_app() {
|
||
local pids
|
||
pids="$(find_app_pids)"
|
||
if [[ -n "$pids" ]]; then
|
||
echo "$JAR_NAME 已在运行,PID: $(tr '\n' ' ' <<< "$pids")"
|
||
return 0
|
||
fi
|
||
|
||
if [[ ! -f "$JAR_PATH" ]]; then
|
||
echo "错误:找不到 $JAR_PATH"
|
||
return 1
|
||
fi
|
||
resolve_java || return 1
|
||
|
||
mkdir -p "$LOG_DIR"
|
||
touch "$CONSOLE_LOG"
|
||
echo "以 $(id -un) 用户启动 $JAR_NAME(prod)……"
|
||
nohup "$JAVA_BIN" -jar "$JAR_PATH" --spring.profiles.active=prod >> "$CONSOLE_LOG" 2>&1 &
|
||
|
||
sleep 2
|
||
pids="$(find_app_pids)"
|
||
if [[ -z "$pids" ]]; then
|
||
echo "启动失败,最近日志如下:"
|
||
tail -n 50 "$CONSOLE_LOG" || true
|
||
return 1
|
||
fi
|
||
|
||
echo "启动成功,PID: $(tr '\n' ' ' <<< "$pids")"
|
||
echo "实时日志:tail -f $CONSOLE_LOG"
|
||
}
|
||
|
||
stop_app() {
|
||
local pids pid remaining
|
||
pids="$(find_app_pids)"
|
||
if [[ -z "$pids" ]]; then
|
||
echo "$JAR_NAME 当前未运行。"
|
||
return 0
|
||
fi
|
||
|
||
echo "正在停止 $JAR_NAME,PID: $(tr '\n' ' ' <<< "$pids")"
|
||
while read -r pid; do
|
||
[[ -n "$pid" ]] && kill -TERM "$pid" 2>/dev/null || true
|
||
done <<< "$pids"
|
||
|
||
for _ in {1..30}; do
|
||
[[ -z "$(find_app_pids)" ]] && break
|
||
sleep 1
|
||
done
|
||
|
||
remaining="$(find_app_pids)"
|
||
if [[ -n "$remaining" ]]; then
|
||
echo "服务未在 30 秒内退出,强制停止 PID: $(tr '\n' ' ' <<< "$remaining")"
|
||
while read -r pid; do
|
||
[[ -n "$pid" ]] && kill -KILL "$pid" 2>/dev/null || true
|
||
done <<< "$remaining"
|
||
sleep 1
|
||
fi
|
||
|
||
remaining="$(find_app_pids)"
|
||
if [[ -n "$remaining" ]]; then
|
||
echo "错误:服务仍在运行,PID: $(tr '\n' ' ' <<< "$remaining");请检查执行用户和进程权限。"
|
||
return 1
|
||
fi
|
||
echo "$JAR_NAME 已停止。"
|
||
}
|
||
|
||
show_status() {
|
||
local pids
|
||
pids="$(find_app_pids)"
|
||
if [[ -n "$pids" ]]; then
|
||
echo "$JAR_NAME 正在运行,PID: $(tr '\n' ' ' <<< "$pids")"
|
||
else
|
||
echo "$JAR_NAME 当前未运行。"
|
||
fi
|
||
}
|
||
|
||
case "${1:-}" in
|
||
start)
|
||
start_app
|
||
;;
|
||
stop)
|
||
stop_app
|
||
;;
|
||
restart)
|
||
stop_app && start_app
|
||
;;
|
||
status)
|
||
show_status
|
||
;;
|
||
*)
|
||
usage
|
||
exit 2
|
||
;;
|
||
esac
|