#!/bin/sh set -eu WEBAPP_ROOT="/home/webapp" ENV_ROOT="$WEBAPP_ROOT/env" APP_ROOT="$WEBAPP_ROOT/loan-pricing" JAVA_HOME="$ENV_ROOT/jdk" BACKEND_DIR="$APP_ROOT/backend" LOG_DIR="$APP_ROOT/logs" RUN_DIR="$APP_ROOT/run" BACKEND_PID_FILE="$RUN_DIR/backend.pid" BACKEND_JAR="$BACKEND_DIR/ruoyi-admin.jar" BACKEND_CONSOLE_LOG="$LOG_DIR/backend-console.log" BACKEND_PORT=63310 BACKEND_MARKER="-Dloan.pricing.home=$APP_ROOT" JAVA_OPTS="$BACKEND_MARKER -Duser.timezone=Asia/Shanghai -Xms512m -Xmx1024m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=512m -XX:+HeapDumpOnOutOfMemoryError" timestamp() { date "+%Y-%m-%d %H:%M:%S" } log_info() { printf '[%s] %s\n' "$(timestamp)" "$1" } log_error() { printf '[%s] %s\n' "$(timestamp)" "$1" >&2 } usage() { cat <<'EOF' 用法: ./restart_java.sh [start|stop|restart|status] 默认动作: restart 重启后端 Java 进程 EOF } ensure_runtime_dirs() { mkdir -p "$BACKEND_DIR" "$LOG_DIR" "$RUN_DIR" } is_managed_backend_pid() { pid="$1" if [ -z "${pid:-}" ] || ! kill -0 "$pid" 2>/dev/null; then return 1 fi args=$(ps -o args= -p "$pid" 2>/dev/null || true) if [ -z "${args:-}" ]; then return 1 fi case "$args" in *"$BACKEND_MARKER"*"$BACKEND_JAR"*|*"$BACKEND_JAR"*"$BACKEND_MARKER"*) return 0 ;; esac return 1 } collect_backend_pids() { pids="" if [ -f "$BACKEND_PID_FILE" ]; then file_pid=$(cat "$BACKEND_PID_FILE" 2>/dev/null || true) if [ -n "${file_pid:-}" ] && is_managed_backend_pid "$file_pid"; then pids="$pids $file_pid" fi fi marker_pids=$(pgrep -f "$BACKEND_MARKER" 2>/dev/null || true) if [ -n "${marker_pids:-}" ]; then for pid in $marker_pids; do if is_managed_backend_pid "$pid"; then pids="$pids $pid" fi done fi printf '%s\n' "$(echo "$pids" | xargs 2>/dev/null || true)" } stop_backend() { pids=$(collect_backend_pids) if [ -z "${pids:-}" ]; then rm -f "$BACKEND_PID_FILE" log_info "未发现运行中的后端进程" return 0 fi log_info "停止后端进程: $pids" for pid in $pids; do kill -TERM "$pid" 2>/dev/null || true done elapsed=0 while [ "$elapsed" -lt 30 ]; do remaining="" for pid in $pids; do if kill -0 "$pid" 2>/dev/null; then remaining="$remaining $pid" fi done remaining=$(echo "$remaining" | xargs 2>/dev/null || true) if [ -z "${remaining:-}" ]; then break fi sleep 1 elapsed=$((elapsed + 1)) done if [ -n "${remaining:-}" ]; then log_info "执行强制停止: $remaining" for pid in $remaining; do kill -KILL "$pid" 2>/dev/null || true done fi rm -f "$BACKEND_PID_FILE" } start_backend() { ensure_runtime_dirs if [ ! -x "$JAVA_HOME/bin/java" ]; then log_error "未检测到可执行 Java: $JAVA_HOME/bin/java" exit 1 fi if [ ! -f "$BACKEND_JAR" ]; then log_error "未找到后端 jar: $BACKEND_JAR" exit 1 fi if [ -n "$(collect_backend_pids)" ]; then log_error "检测到后端已在运行,请先执行 stop 或 restart" exit 1 fi printf '\n===== %s restart =====\n' "$(timestamp)" >> "$BACKEND_CONSOLE_LOG" ( cd "$BACKEND_DIR" nohup "$JAVA_HOME/bin/java" $JAVA_OPTS -jar "$BACKEND_JAR" --spring.profiles.active=pro --server.port="$BACKEND_PORT" >> "$BACKEND_CONSOLE_LOG" 2>&1 & echo $! > "$BACKEND_PID_FILE" ) sleep 3 backend_pid=$(cat "$BACKEND_PID_FILE" 2>/dev/null || true) if [ -z "${backend_pid:-}" ] || ! kill -0 "$backend_pid" 2>/dev/null; then log_error "后端启动失败,请检查日志: $BACKEND_CONSOLE_LOG" exit 1 fi log_info "后端已启动,PID: $backend_pid" } status_backend() { pids=$(collect_backend_pids) if [ -n "${pids:-}" ]; then log_info "后端正在运行,进程: $pids" return 0 fi log_info "后端未运行" } main() { action="${1:-restart}" case "$action" in start) start_backend ;; stop) stop_backend ;; restart) stop_backend start_backend ;; status) status_backend ;; *) usage exit 1 ;; esac } main "$@"