后端脚本:
PASSWORD={your_password}
SOURCE={java_project_Paht}
TARGET={user_name}@{server_ip}
PACK_FILE=dist.tar.gz;
sshpass -p $PASSWORD ssh $TARGET "sh -c '${PROJECT_PATH}/app.sh stop'";
sshpass -p $PASSWORD ssh $TARGET "sh -c 'rm ${PROJECT_PATH}/*.gz'";
sshpass -p $PASSWORD ssh $TARGET "sh -c 'rm ${PROJECT_PATH}/*.jar'";
sshpass -p $PASSWORD ssh $TARGET "sh -c 'rm -rf ${PROJECT_PATH}/lib'";
cd $SOURCE/target;
tar -zcvf $PACK_FILE *.jar lib;
sshpass -p $PASSWORD scp ${SOURCE}/target/$PACK_FILE ${TARGET}:${PROJECT_PATH};
sshpass -p $PASSWORD ssh $TARGET "sh -c 'tar -xvf ${PROJECT_PATH}/$PACK_FILE -C ${PROJECT_PATH}'";
sshpass -p $PASSWORD ssh $TARGET "sh -c '${PROJECT_PATH}/app.sh start'";
对应的启动脚本:
#!/bin/bash
NODE=dev
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 128m -xmx 256m"
# 查找进程 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
}
# 根据传入的参数执行相应的操作
case "$1" in
start)
start
;;
stop)
stop
;;
restart)
restart
;;
status)
status
;;
run)
run
;;
*)
echo "使用方法: $0 {start|stop|restart|status|run}"
exit 1
;;
esac
exit 0
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END