systemd服务单元,放到/etc/systemd/system中:
#hqs-omp.service
[Unit]
# 服务描述
Description=HQS-OMP Service
# 启动顺序:网络就绪后再启动
After=network.target
[Service]
# 核心:直接执行你的 SH 启动脚本
ExecStart=/data/hqs/server/omp/app.sh service
ExecStop=/bin/bash /data/hqs/server/omp/app.sh stop
# 工作目录(必须和你脚本运行的目录一致)
WorkingDirectory=/data/hqs/server/omp
# 服务运行方式:简单模式(直接运行脚本)
Type=simple
# 可选:进程异常退出后自动重启
Restart=on-failure
# 重启间隔
RestartSec=5
StartLimitInterval=60s
StartLimitBurst=3
# 可选:设置 Java 服务的用户/用户组(推荐用普通用户,不要用 root)
User=hqs
Group=hqs
# 标准输出重定向(日志会存到系统日志里)
StandardOutput=journal+console
StandardError=journal+console
[Install]
# 多用户模式下自启
WantedBy=multi-user.target
root@MSI:/etc/systemd/system#
关于ExecStart:
#顺序启动
ExecStart=/bin/bash -c "/script1.sh; /script2.sh"
#并行启动
ExecStart=/bin/bash -c "/script1.sh & /script2.sh & wait"
启动脚本app.sh
#!/bin/bash
export NODE=node1
SCRIPT_DIR=$(cd "$(dirname "$0")" && pwd)
# 若脚本通过符号链接执行(可选增强)
if [ -L "$0" ]; then
SCRIPT_REAL_PATH=$(readlink -f "$0")
SCRIPT_DIR=$(dirname "$SCRIPT_REAL_PATH")
fi
echo "脚本所在绝对路径:$SCRIPT_DIR"
cd $SCRIPT_DIR
# 自动识别 JAR 包
JAR_NAME=$(find . -maxdepth 1 -name "*.jar" | head -n 1)
if [ -z "$JAR_NAME" ]; then
echo "当前目录下未找到 .jar 文件。"
exit 1
fi
# 获取 JAR 包的完整物理路径
JAR_FULL_PATH=$(realpath "$JAR_NAME")
echo "JAR 包路径:$JAR_FULL_PATH"
# 去除路径信息,只保留文件名
JAR_NAME=$(basename "$JAR_NAME")
# 定义日志文件路径
LOG_FILE="logs/console.log"
OPT="-xms 32m -xmx 256m --server.port=28001"
# 查找进程 PID,同时匹配 JAR 包名和 node 名称
find_pid() {
local jar_name=$1
local node_name=$2
local result=$(ps -ef | grep "$jar_name" | grep -- "-node=$node_name" | grep -v grep | awk '{print $2}')
#echo "查找 $jar_name 和 -node=$node_name 的 PID 结果: $result" >&2 # 将调试信息输出到标准错误输出
echo "$result"
}
# 定义获取进程信息的函数
get_process_info() {
PID=$(find_pid "$JAR_NAME" "$NODE")
if [ -n "$PID" ]; then
# 读取 /proc/$PID/cmdline 文件获取启动命令
CMDLINE=$(cat /proc/$PID/cmdline | tr '\0' ' ')
# 提取 JAR 包路径
JAR_PATH=$(echo "$CMDLINE" | grep -oP '(?<=java -jar )[^ ]+')
echo "进程 ID: $PID"
echo "进程启动的 JAR 包: $JAR_PATH"
fi
}
# 定义启动函数,传递 node 参数
start() {
get_process_info
if [ -n "$PID" ]; then
echo "Spring Boot 应用 $JAR_NAME 在节点 $NODE 已经在运行中。"
else
nohup java -jar $JAR_NAME -node=$NODE $OPT > $LOG_FILE 2>&1 &
MAX_ATTEMPTS=60
ATTEMPT=0
while [ $ATTEMPT -lt $MAX_ATTEMPTS ]; do
PID=$(find_pid "$JAR_NAME" "$NODE")
if [ -n "$PID" ]; then
echo "Spring Boot 应用 $JAR_NAME 在节点 $NODE 启动成功。"
get_process_info
break
fi
sleep 1
ATTEMPT=$((ATTEMPT + 1))
done
if [ $ATTEMPT -eq $MAX_ATTEMPTS ]; then
echo "Spring Boot 应用 $JAR_NAME 在节点 $NODE 启动失败,请查看 $LOG_FILE 文件。"
fi
fi
}
# 定义停止函数
stop() {
PID=$(find_pid "$JAR_NAME" "$NODE")
if [ -z "$PID" ]; then
echo "Spring Boot 应用 $JAR_NAME 在节点 $NODE 未在运行。"
else
echo "正在停止 Spring Boot 应用 $JAR_NAME 在节点 $NODE,PID 为 $PID..."
kill $PID
MAX_ATTEMPTS=60
ATTEMPT=0
while [ $ATTEMPT -lt $MAX_ATTEMPTS ]; do
PID=$(find_pid "$JAR_NAME" "$NODE")
if [ -z "$PID" ]; then
echo "Spring Boot 应用 $JAR_NAME 在节点 $NODE 已停止。"
break
fi
sleep 1
ATTEMPT=$((ATTEMPT + 1))
done
if [ $ATTEMPT -eq $MAX_ATTEMPTS ]; then
echo "尝试强制停止 Spring Boot 应用 $JAR_NAME 在节点 $NODE..."
kill -9 $PID
sleep 2
PID=$(find_pid "$JAR_NAME" "$NODE")
if [ -z "$PID" ]; then
echo "Spring Boot 应用 $JAR_NAME 在节点 $NODE 已通过强制手段停止。"
else
echo "无法停止 Spring Boot 应用 $JAR_NAME 在节点 $NODE,请手动检查。"
fi
fi
fi
}
# 定义重启函数
restart() {
stop
start
}
# 定义查看状态函数
status() {
PID=$(find_pid "$JAR_NAME" "$NODE")
if [ -n "$PID" ]; then
echo "Spring Boot 应用 $JAR_NAME 在节点 $NODE 正在运行。"
echo "进程 ID: $PID"
get_process_info
else
echo "Spring Boot 应用 $JAR_NAME 在节点 $NODE 未在运行。"
fi
}
# 定义直接运行函数
run() {
get_process_info
if [ -n "$PID" ]; then
echo "Spring Boot 应用 $JAR_NAME 在节点 $NODE 已经在运行中。"
echo "进程 ID: $PID"
else
echo "正在直接运行 Spring Boot 应用 $JAR_NAME 在节点 $NODE,按 Ctrl+C 可结束。"
java -jar $JAR_NAME -node=$NODE $OPT
fi
}
# 定义在Systemd运行
service(){
get_process_info
if [ -n "$PID" ]; then
echo "Spring Boot 应用 $JAR_NAME 在节点 $NODE 已经在运行中。"
else
exec java -jar $JAR_NAME -node=$NODE $OPT > $LOG_FILE 2>&1
MAX_ATTEMPTS=60
ATTEMPT=0
while [ $ATTEMPT -lt $MAX_ATTEMPTS ]; do
PID=$(find_pid "$JAR_NAME" "$NODE")
if [ -n "$PID" ]; then
echo "Spring Boot 应用 $JAR_NAME 在节点 $NODE 启动成功。"
get_process_info
break
fi
sleep 1
ATTEMPT=$((ATTEMPT + 1))
done
if [ $ATTEMPT -eq $MAX_ATTEMPTS ]; then
echo "Spring Boot 应用 $JAR_NAME 在节点 $NODE 启动失败,请查看 $LOG_FILE 文件。"
fi
fi
}
# 根据传入的参数执行相应的操作
case "$1" in
start)
start
;;
service)
service
;;
stop)
stop
;;
restart)
restart
;;
status)
status
;;
run)
run
;;
*)
echo "使用方法: $0 {start|run|service|stop|restart|status}"
exit 1
;;
esac
exit 0
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END



























![[PDF文件格式参考]PDF Reference 1.7-JoyCode 斑马快跑](https://qiniu.joycode.com.cn/2020/10/20201011222013698208.jpeg)
