将java包装为服务启动

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
喜欢就支持一下吧
点赞0 分享