feat: 脚本支持多租户实例部署

- env.properties新增APP_NAME、INSTANCE_NAME、TENANT_ID配置
- APP_NAME: 服务名称(对应JAR文件名)
- INSTANCE_NAME: 实例名称(区分多租户实例,用于日志目录和PID文件)
- TENANT_ID: 租户标识(用于Nacos元数据路由)
- start.sh传递spring.application.name和TENANT_ID参数
- stop.sh和status.sh同步支持INSTANCE_NAME
This commit is contained in:
zhangjf 2026-02-22 15:46:09 +08:00
parent faded43266
commit 3e73b6c086
4 changed files with 101 additions and 32 deletions

View File

@ -3,6 +3,17 @@
# 服务启动时会加载此文件 # 服务启动时会加载此文件
# ============================================ # ============================================
# --------------------------------------------
# 服务标识配置
# --------------------------------------------
# 服务名称对应JAR文件名如fund-sys
APP_NAME=fund-sys
# 实例名称用于区分多租户实例如fund-sys-shared, fund-sys-vip001
# 默认与APP_NAME相同多租户模式下需要修改
INSTANCE_NAME=${APP_NAME}
# 租户标识多租户模式使用用于Nacos元数据路由
TENANT_ID=
# -------------------------------------------- # --------------------------------------------
# Nacos配置所有服务共用 # Nacos配置所有服务共用
# -------------------------------------------- # --------------------------------------------

View File

@ -1,35 +1,57 @@
#!/bin/bash #!/bin/bash
# 服务启动脚本 # 服务启动脚本
# 自动从目录名推断服务名称 # 支持多租户模式:同一服务可部署多个实例(数据库连接不同)
# 获取脚本所在目录和服务名 # 获取脚本所在目录
SCRIPT_DIR=$(dirname "$(readlink -f "$0")") SCRIPT_DIR=$(dirname "$(readlink -f "$0")")
APP_HOME=$(dirname "$SCRIPT_DIR") APP_HOME=$(dirname "$SCRIPT_DIR")
APP_NAME=$(basename "$APP_HOME")
# 日志目录 # 加载环境变量配置优先从env.properties读取
LOG_HOME="/datacfs/applogs/${APP_NAME}" if [ -f "${APP_HOME}/conf/env.properties" ]; then
# 读取APP_NAME和INSTANCE_NAME
while IFS='=' read -r key value; do
# 跳过注释和空行
[[ "$key" =~ ^#.*$ ]] && continue
[[ -z "$key" ]] && continue
# 去除前后空格
key=$(echo "$key" | xargs)
value=$(echo "$value" | xargs)
# 导出环境变量
export "$key=$value"
done < "${APP_HOME}/conf/env.properties"
fi
# JAR文件路径 # 服务名称对应JAR文件名从env.properties读取或从目录名推断
APP_NAME=${APP_NAME:-$(basename "$APP_HOME")}
# 实例名称用于区分多租户实例默认与APP_NAME相同
INSTANCE_NAME=${INSTANCE_NAME:-${APP_NAME}}
# 日志目录使用INSTANCE_NAME区分不同实例
LOG_HOME="/datacfs/applogs/${INSTANCE_NAME}"
# JAR文件路径使用APP_NAME找JAR
JAR_FILE="${APP_HOME}/lib/${APP_NAME}.jar" JAR_FILE="${APP_HOME}/lib/${APP_NAME}.jar"
# PID文件路径 # PID文件路径使用INSTANCE_NAME
PID_FILE="${APP_HOME}/${APP_NAME}.pid" PID_FILE="${APP_HOME}/${INSTANCE_NAME}.pid"
# 加载环境变量配置(如果存在)
if [ -f "${APP_HOME}/conf/env.properties" ]; then
source "${APP_HOME}/conf/env.properties"
fi
# JVM参数可通过环境变量覆盖 # JVM参数可通过环境变量覆盖
JAVA_OPTS="${JAVA_OPTS:--Xms256m -Xmx512m -XX:+UseG1GC -XX:MaxGCPauseMillis=200}" JAVA_OPTS="${JAVA_OPTS:--Xms256m -Xmx512m -XX:+UseG1GC -XX:MaxGCPauseMillis=200}"
# 日志参数从env.properties读取或使用默认值 # 日志参数从env.properties读取或使用默认值
LOG_OPTS="-Dlogging.file.path=${LOG_HOME} -DAPP_NAME=${APP_NAME}" LOG_OPTS="-Dlogging.file.path=${LOG_HOME}"
LOG_OPTS="$LOG_OPTS -Dspring.application.name=${APP_NAME}"
LOG_OPTS="$LOG_OPTS -Dlogging.level.root=${LOG_LEVEL_ROOT:-INFO}" LOG_OPTS="$LOG_OPTS -Dlogging.level.root=${LOG_LEVEL_ROOT:-INFO}"
LOG_OPTS="$LOG_OPTS -Dlogging.level.app=${LOG_LEVEL_APP:-DEBUG}" LOG_OPTS="$LOG_OPTS -Dlogging.level.app=${LOG_LEVEL_APP:-DEBUG}"
LOG_OPTS="$LOG_OPTS -Dlogging.pattern.console=${LOG_PATTERN}" LOG_OPTS="$LOG_OPTS -Dlogging.pattern.console=${LOG_PATTERN}"
# 多租户参数
TENANT_OPTS=""
if [ -n "${TENANT_ID}" ]; then
TENANT_OPTS="-DTENANT_ID=${TENANT_ID}"
fi
# 配置文件路径 # 配置文件路径
CONFIG_OPTS="--spring.config.location=${APP_HOME}/conf/application.yml" CONFIG_OPTS="--spring.config.location=${APP_HOME}/conf/application.yml"
@ -37,7 +59,7 @@ CONFIG_OPTS="--spring.config.location=${APP_HOME}/conf/application.yml"
if [ -f "$PID_FILE" ]; then if [ -f "$PID_FILE" ]; then
PID=$(cat $PID_FILE) PID=$(cat $PID_FILE)
if ps -p $PID > /dev/null 2>&1; then if ps -p $PID > /dev/null 2>&1; then
echo "${APP_NAME} is already running (PID: $PID)" echo "${INSTANCE_NAME} is already running (PID: $PID)"
exit 1 exit 1
fi fi
fi fi
@ -46,13 +68,18 @@ fi
mkdir -p ${LOG_HOME} mkdir -p ${LOG_HOME}
# 启动服务 # 启动服务
echo "Starting ${APP_NAME}..." echo "Starting ${INSTANCE_NAME}..."
echo " APP_NAME: ${APP_NAME}"
echo " INSTANCE_NAME: ${INSTANCE_NAME}"
echo " APP_HOME: ${APP_HOME}" echo " APP_HOME: ${APP_HOME}"
echo " LOG_HOME: ${LOG_HOME}" echo " LOG_HOME: ${LOG_HOME}"
echo " JAVA_OPTS: ${JAVA_OPTS}" echo " JAVA_OPTS: ${JAVA_OPTS}"
if [ -n "${TENANT_ID}" ]; then
echo " TENANT_ID: ${TENANT_ID}"
fi
nohup java $JAVA_OPTS $LOG_OPTS -jar $JAR_FILE $CONFIG_OPTS > /dev/null 2>&1 & nohup java $JAVA_OPTS $LOG_OPTS $TENANT_OPTS -jar $JAR_FILE $CONFIG_OPTS > /dev/null 2>&1 &
# 保存PID # 保存PID
echo $! > $PID_FILE echo $! > $PID_FILE
echo "${APP_NAME} started (PID: $(cat $PID_FILE))" echo "${INSTANCE_NAME} started (PID: $(cat $PID_FILE))"

View File

@ -1,17 +1,31 @@
#!/bin/bash #!/bin/bash
# 查看服务状态 # 查看服务状态
# 自动从目录名推断服务名称 # 支持多租户模式
# 获取脚本所在目录和服务名 # 获取脚本所在目录
SCRIPT_DIR=$(dirname "$(readlink -f "$0")") SCRIPT_DIR=$(dirname "$(readlink -f "$0")")
APP_HOME=$(dirname "$SCRIPT_DIR") APP_HOME=$(dirname "$SCRIPT_DIR")
APP_NAME=$(basename "$APP_HOME")
# 加载环境变量配置
if [ -f "${APP_HOME}/conf/env.properties" ]; then
while IFS='=' read -r key value; do
[[ "$key" =~ ^#.*$ ]] && continue
[[ -z "$key" ]] && continue
key=$(echo "$key" | xargs)
value=$(echo "$value" | xargs)
export "$key=$value"
done < "${APP_HOME}/conf/env.properties"
fi
# 服务名称和实例名称
APP_NAME=${APP_NAME:-$(basename "$APP_HOME")}
INSTANCE_NAME=${INSTANCE_NAME:-${APP_NAME}}
# PID文件路径 # PID文件路径
PID_FILE="${APP_HOME}/${APP_NAME}.pid" PID_FILE="${APP_HOME}/${INSTANCE_NAME}.pid"
echo "==========================================" echo "=========================================="
echo " Service: ${APP_NAME}" echo " Service: ${INSTANCE_NAME}"
echo "==========================================" echo "=========================================="
if [ -f "$PID_FILE" ]; then if [ -f "$PID_FILE" ]; then
@ -20,6 +34,9 @@ if [ -f "$PID_FILE" ]; then
echo -e "Status: \033[32mRUNNING\033[0m" echo -e "Status: \033[32mRUNNING\033[0m"
echo "PID: ${PID}" echo "PID: ${PID}"
echo "Home: ${APP_HOME}" echo "Home: ${APP_HOME}"
if [ -n "${TENANT_ID}" ]; then
echo "Tenant: ${TENANT_ID}"
fi
echo "" echo ""
# 显示进程信息 # 显示进程信息
ps -p $PID -o pid,ppid,%cpu,%mem,etime,cmd --no-headers 2>/dev/null ps -p $PID -o pid,ppid,%cpu,%mem,etime,cmd --no-headers 2>/dev/null

View File

@ -1,30 +1,44 @@
#!/bin/bash #!/bin/bash
# 服务停止脚本 # 服务停止脚本
# 自动从目录名推断服务名称 # 支持多租户模式
# 获取脚本所在目录和服务名 # 获取脚本所在目录
SCRIPT_DIR=$(dirname "$(readlink -f "$0")") SCRIPT_DIR=$(dirname "$(readlink -f "$0")")
APP_HOME=$(dirname "$SCRIPT_DIR") APP_HOME=$(dirname "$SCRIPT_DIR")
APP_NAME=$(basename "$APP_HOME")
# 加载环境变量配置
if [ -f "${APP_HOME}/conf/env.properties" ]; then
while IFS='=' read -r key value; do
[[ "$key" =~ ^#.*$ ]] && continue
[[ -z "$key" ]] && continue
key=$(echo "$key" | xargs)
value=$(echo "$value" | xargs)
export "$key=$value"
done < "${APP_HOME}/conf/env.properties"
fi
# 服务名称和实例名称
APP_NAME=${APP_NAME:-$(basename "$APP_HOME")}
INSTANCE_NAME=${INSTANCE_NAME:-${APP_NAME}}
# PID文件路径 # PID文件路径
PID_FILE="${APP_HOME}/${APP_NAME}.pid" PID_FILE="${APP_HOME}/${INSTANCE_NAME}.pid"
# 检查是否运行 # 检查是否运行
if [ ! -f "$PID_FILE" ]; then if [ ! -f "$PID_FILE" ]; then
echo "${APP_NAME} is not running" echo "${INSTANCE_NAME} is not running"
exit 0 exit 0
fi fi
PID=$(cat $PID_FILE) PID=$(cat $PID_FILE)
if ! ps -p $PID > /dev/null 2>&1; then if ! ps -p $PID > /dev/null 2>&1; then
echo "${APP_NAME} is not running" echo "${INSTANCE_NAME} is not running"
rm -f $PID_FILE rm -f $PID_FILE
exit 0 exit 0
fi fi
# 停止服务 # 停止服务
echo "Stopping ${APP_NAME} (PID: $PID)..." echo "Stopping ${INSTANCE_NAME} (PID: $PID)..."
kill $PID kill $PID
# 等待停止 # 等待停止
@ -37,9 +51,9 @@ done
# 强制停止 # 强制停止
if ps -p $PID > /dev/null 2>&1; then if ps -p $PID > /dev/null 2>&1; then
echo "Force killing ${APP_NAME}..." echo "Force killing ${INSTANCE_NAME}..."
kill -9 $PID kill -9 $PID
fi fi
rm -f $PID_FILE rm -f $PID_FILE
echo "${APP_NAME} stopped" echo "${INSTANCE_NAME} stopped"