diff --git a/bms-back/deploy.sh b/bms-back/deploy.sh new file mode 100644 index 00000000..eae4dae3 --- /dev/null +++ b/bms-back/deploy.sh @@ -0,0 +1,154 @@ +#!/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