Files
loan-pricing/bin/prod/deploy_from_package.sh

258 lines
6.5 KiB
Bash
Executable File
Raw 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.
#!/bin/sh
set -eu
JAVA_BIN="/home/webapp/env/java/bin/java"
BACKEND_PORT=63310
SPRING_PROFILE="uat"
JAVA_OPTS="-Duser.timezone=Asia/Shanghai -Xms512m -Xmx1024m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=512m -XX:+HeapDumpOnOutOfMemoryError"
SCRIPT_DIR=$(CDPATH= cd -- "$(dirname "$0")" && pwd)
BACKEND_DIR="$SCRIPT_DIR/backend"
FRONTEND_DIR="$SCRIPT_DIR/frontend"
BACKEND_JAR_TARGET="$BACKEND_DIR/ruoyi-admin.jar"
BACKEND_PID_FILE="$BACKEND_DIR/backend.pid"
BACKEND_LOG_FILE="$BACKEND_DIR/backend-console.log"
FRONTEND_DIST_ARCHIVE="$FRONTEND_DIR/dist.zip"
FRONTEND_DIST_DIR="$FRONTEND_DIR/dist"
BACKEND_MARKER="-Dloan.pricing.home=$SCRIPT_DIR"
usage() {
cat <<'EOF'
用法:
./deploy_from_package.sh
EOF
}
timestamp() {
date "+%Y%m%d%H%M%S"
}
log_info() {
printf '[%s] %s\n' "$(date '+%Y-%m-%d %H:%M:%S')" "$1"
}
log_error() {
printf '[%s] %s\n' "$(date '+%Y-%m-%d %H:%M:%S')" "$1" >&2
}
cleanup() {
if [ -n "${WORK_DIR:-}" ] && [ -d "$WORK_DIR" ]; then
rm -rf "$WORK_DIR"
fi
}
require_dir() {
if [ ! -d "$1" ]; then
log_error "缺少目录: $1"
exit 1
fi
}
require_command() {
if ! command -v "$1" >/dev/null 2>&1; then
log_error "缺少命令: $1"
exit 1
fi
}
find_release_archive() {
archives=$(find "$SCRIPT_DIR" -maxdepth 1 -type f -name '*.zip' ! -name 'dist.zip')
count=$(printf '%s\n' "$archives" | sed '/^$/d' | wc -l | tr -d ' ')
if [ "$count" -ne 1 ]; then
log_error "脚本同目录发布 zip 数量不正确,期望 1 个,实际 $count"
exit 1
fi
printf '%s\n' "$archives"
}
extract_release_package() {
release_archive="$1"
release_extract_dir="$2"
mkdir -p "$release_extract_dir"
unzip -oq "$release_archive" -d "$release_extract_dir"
}
assert_single_jar() {
search_dir="$1"
count=$(find "$search_dir" -type f -name '*.jar' ! -path '*/__MACOSX/*' ! -name '._*' | wc -l | tr -d ' ')
if [ "$count" -ne 1 ]; then
log_error "后端 jar 数量不正确,期望 1 个,实际 $count"
exit 1
fi
find "$search_dir" -type f -name '*.jar' ! -path '*/__MACOSX/*' ! -name '._*' | head -n 1
}
assert_single_dist_zip() {
search_dir="$1"
count=$(find "$search_dir" -type f -name 'dist.zip' ! -path '*/__MACOSX/*' ! -name '._*' | wc -l | tr -d ' ')
if [ "$count" -ne 1 ]; then
log_error "前端 dist.zip 数量不正确,期望 1 个,实际 $count"
exit 1
fi
find "$search_dir" -type f -name 'dist.zip' ! -path '*/__MACOSX/*' ! -name '._*' | head -n 1
}
backup_backend_jar() {
if [ -f "$BACKEND_JAR_TARGET" ]; then
mv "$BACKEND_JAR_TARGET" "$BACKEND_JAR_TARGET.$(timestamp).bak"
fi
}
backup_frontend_dist() {
if [ -d "$FRONTEND_DIST_DIR" ]; then
mv "$FRONTEND_DIST_DIR" "$FRONTEND_DIR/dist-$(timestamp)"
fi
}
deploy_backend_jar() {
source_jar="$1"
mv "$source_jar" "$BACKEND_JAR_TARGET"
}
deploy_frontend_dist() {
source_dist_zip="$1"
rm -f "$FRONTEND_DIST_ARCHIVE"
rm -rf "$FRONTEND_DIST_DIR"
mv "$source_dist_zip" "$FRONTEND_DIST_ARCHIVE"
unzip -oq "$FRONTEND_DIST_ARCHIVE" -d "$FRONTEND_DIR"
if [ ! -d "$FRONTEND_DIST_DIR" ]; then
log_error "dist.zip 解压后未找到 $FRONTEND_DIST_DIR"
exit 1
fi
}
collect_backend_pids() {
ps -ef | awk -v marker="$BACKEND_MARKER" -v jar="$BACKEND_JAR_TARGET" '
index($0, "<defunct>") == 0 && index($0, marker) > 0 {
for (i = 1; i < NF; i++) {
if ($i == "-jar" && $(i + 1) == jar) {
print $2
break
}
}
}
' | xargs 2>/dev/null || true
}
stop_backend() {
pids=$(collect_backend_pids)
if [ -z "${pids:-}" ]; then
rm -f "$BACKEND_PID_FILE"
log_info "未发现运行中的后端进程"
return 0
fi
log_info "停止后端进程: $pids"
for pid in $pids; do
kill -TERM "$pid" 2>/dev/null || true
done
elapsed=0
remaining="$pids"
while [ "$elapsed" -lt 30 ]; do
remaining=""
for pid in $pids; do
if kill -0 "$pid" 2>/dev/null; then
remaining="$remaining $pid"
fi
done
remaining=$(echo "$remaining" | xargs 2>/dev/null || true)
if [ -z "${remaining:-}" ]; then
break
fi
sleep 1
elapsed=$((elapsed + 1))
done
if [ -n "${remaining:-}" ]; then
log_info "执行强制停止: $remaining"
for pid in $remaining; do
kill -KILL "$pid" 2>/dev/null || true
done
fi
rm -f "$BACKEND_PID_FILE"
}
start_backend() {
if [ ! -x "$JAVA_BIN" ]; then
log_error "未检测到可执行 Java: $JAVA_BIN"
exit 1
fi
if [ ! -f "$BACKEND_JAR_TARGET" ]; then
log_error "未找到后端 jar: $BACKEND_JAR_TARGET"
exit 1
fi
if [ -n "$(collect_backend_pids)" ]; then
log_error "检测到后端已在运行,请先停止旧进程"
exit 1
fi
printf '\n===== %s deploy =====\n' "$(date '+%Y-%m-%d %H:%M:%S')" >> "$BACKEND_LOG_FILE"
nohup "$JAVA_BIN" $JAVA_OPTS "$BACKEND_MARKER" -jar "$BACKEND_JAR_TARGET" \
--spring.profiles.active="$SPRING_PROFILE" \
--server.port="$BACKEND_PORT" >> "$BACKEND_LOG_FILE" 2>&1 &
backend_pid=$!
printf '%s\n' "$backend_pid" > "$BACKEND_PID_FILE"
sleep 1
if ! kill -0 "$backend_pid" 2>/dev/null; then
log_error "后端启动失败,请检查日志: $BACKEND_LOG_FILE"
exit 1
fi
log_info "后端已启动PID: $backend_pid"
}
main() {
if [ "$#" -ne 0 ]; then
usage
exit 1
fi
require_dir "$BACKEND_DIR"
require_dir "$FRONTEND_DIR"
require_command unzip
require_command find
require_command ps
require_command nohup
release_archive=$(find_release_archive)
WORK_DIR=$(mktemp -d "${TMPDIR:-/tmp}/deploy_from_package.XXXXXX")
trap cleanup EXIT INT TERM
extract_release_package "$release_archive" "$WORK_DIR/package"
backend_jar_source=$(assert_single_jar "$WORK_DIR/package")
frontend_dist_source=$(assert_single_dist_zip "$WORK_DIR/package")
backup_backend_jar
backup_frontend_dist
stop_backend
deploy_backend_jar "$backend_jar_source"
deploy_frontend_dist "$frontend_dist_source"
start_backend
log_info "部署完成"
log_info "后端 jar: $BACKEND_JAR_TARGET"
log_info "前端目录: $FRONTEND_DIST_DIR"
}
main "$@"