xinli/start.sh
2026-02-24 16:49:05 +08:00

124 lines
3.8 KiB
Bash
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env bash
set -euo pipefail
# ====== 可改配置 ======
APP_NAME="xinli-server"
PORT="30081"
JAR_NAME="ry-xinli-admin.jar" # 改成你的实际jar文件名
APP_HOME="$(cd "$(dirname "$0")" && pwd)"
JAR_PATH="${APP_HOME}/${JAR_NAME}"
LOG_DIR="${APP_HOME}/logs"
LOG_FILE="${LOG_DIR}/${APP_NAME}.log"
PID_FILE="${APP_HOME}/${APP_NAME}.pid"
JAVA_OPTS="-Xms512m -Xmx1024m -Dfile.encoding=UTF-8"
SPRING_OPTS="--server.port=${PORT} --server.address=0.0.0.0"
# 如果你走 Python RAG可选
export RAG_PYTHON_URL="${RAG_PYTHON_URL:-http://127.0.0.1:5000}"
# ======================
mkdir -p "${LOG_DIR}"
echo "[1/4] 检查 jar 是否存在:${JAR_PATH}"
if [[ ! -f "${JAR_PATH}" ]]; then
echo "ERROR: jar 不存在:${JAR_PATH}"
exit 1
fi
kill_by_port() {
local port="$1"
local pids=""
# 优先用 lsof
if command -v lsof >/dev/null 2>&1; then
pids="$(lsof -ti tcp:${port} 2>/dev/null || true)"
# 再用 ss大多数 Linux 有)
elif command -v ss >/dev/null 2>&1; then
# 从 ss 输出里提取 pid=xxxx
pids="$(ss -lntp 2>/dev/null | awk -v p=":${port}" '$4 ~ p {print $0}' | sed -n 's/.*pid=\\([0-9]\\+\\).*/\\1/p' | sort -u)"
# 再用 netstat老系统
elif command -v netstat >/dev/null 2>&1; then
pids="$(netstat -lntp 2>/dev/null | awk -v p=":${port}" '$4 ~ p {print $7}' | cut -d/ -f1 | grep -E '^[0-9]+$' | sort -u)"
else
echo "ERROR: 找不到 lsof/ss/netstat无法通过端口查进程。请先安装 lsof推荐。"
exit 1
fi
if [[ -n "${pids}" ]]; then
echo "[2/4] 端口 ${port} 被占用,准备杀进程:${pids}"
for pid in ${pids}; do
echo " - kill ${pid}"
kill "${pid}" 2>/dev/null || true
done
# 等待退出,最多 10 秒
for _ in {1..10}; do
sleep 1
local still=""
if command -v lsof >/dev/null 2>&1; then
still="$(lsof -ti tcp:${port} 2>/dev/null || true)"
elif command -v ss >/dev/null 2>&1; then
still="$(ss -lntp 2>/dev/null | awk -v p=":${port}" '$4 ~ p {print $0}' | sed -n 's/.*pid=\\([0-9]\\+\\).*/\\1/p' | sort -u)"
elif command -v netstat >/dev/null 2>&1; then
still="$(netstat -lntp 2>/dev/null | awk -v p=":${port}" '$4 ~ p {print $7}' | cut -d/ -f1 | grep -E '^[0-9]+$' | sort -u)"
fi
[[ -z "${still}" ]] && break
done
# 如果还占用就强杀
if command -v lsof >/dev/null 2>&1; then
pids="$(lsof -ti tcp:${port} 2>/dev/null || true)"
fi
if [[ -n "${pids}" ]]; then
echo "端口仍被占用,强制 kill -9${pids}"
for pid in ${pids}; do
kill -9 "${pid}" 2>/dev/null || true
done
fi
else
echo "[2/4] 端口 ${port} 未占用"
fi
}
stop_by_pidfile() {
if [[ -f "${PID_FILE}" ]]; then
local pid
pid="$(cat "${PID_FILE}" || true)"
if [[ -n "${pid}" ]] && kill -0 "${pid}" >/dev/null 2>&1; then
echo "[2/4] 发现旧 PID_FILE${PID_FILE} (pid=${pid}),先停止旧进程"
kill "${pid}" 2>/dev/null || true
sleep 2
kill -9 "${pid}" 2>/dev/null || true
fi
rm -f "${PID_FILE}" >/dev/null 2>&1 || true
fi
}
echo "[2/4] 停止旧进程(先按 PID_FILE再按端口"
stop_by_pidfile
kill_by_port "${PORT}"
echo "[3/4] 启动应用(日志:${LOG_FILE}"
nohup java ${JAVA_OPTS} -jar "${JAR_PATH}" ${SPRING_OPTS} >> "${LOG_FILE}" 2>&1 &
echo $! > "${PID_FILE}"
echo "已启动pid=$(cat "${PID_FILE}")"
echo "[4/4] 等待端口 ${PORT} 监听(最多 30 秒)"
for i in {1..30}; do
if command -v ss >/dev/null 2>&1; then
if ss -lnt | awk '{print $4}' | grep -q ":${PORT}\$"; then
echo "OK端口已监听。"
echo "查看日志tail -f ${LOG_FILE}"
exit 0
fi
else
# 没有 ss 就不硬等,提示用户看日志
break
fi
sleep 1
done
echo "WARN30 秒内未检测到端口监听,请查看日志排查:${LOG_FILE}"
exit 1