368 lines
10 KiB
Bash
Executable File
368 lines
10 KiB
Bash
Executable File
#!/bin/bash
|
|
|
|
# 情绪博物馆后端服务部署脚本
|
|
# 支持本地部署和远程部署到服务器 101.200.208.45
|
|
|
|
set -e
|
|
|
|
# 配置变量
|
|
APP_NAME="emotion-museum-single"
|
|
JAR_NAME="backend-single-1.0.0.jar"
|
|
JAR_PATH="./target/${JAR_NAME}"
|
|
LOG_DIR="./logs/"
|
|
PID_FILE="/tmp/${APP_NAME}.pid"
|
|
JAVA_OPTS="-Xms512m -Xmx1024m -XX:+UseG1GC -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=${LOG_DIR}/heapdump.hprof"
|
|
|
|
# 远程服务器配置
|
|
REMOTE_HOST="101.200.208.45"
|
|
REMOTE_USER="root"
|
|
REMOTE_DIR="/data/programs/emotion-museum"
|
|
REMOTE_LOG_DIR="/data/logs/emotion-museum"
|
|
REMOTE_JAR_NAME="emotion-single-1.0.0.jar"
|
|
SPRING_PROFILE="test"
|
|
|
|
# 颜色输出
|
|
RED='\033[0;31m'
|
|
GREEN='\033[0;32m'
|
|
YELLOW='\033[1;33m'
|
|
NC='\033[0m' # No Color
|
|
|
|
# 日志函数
|
|
log_info() {
|
|
echo -e "${GREEN}[INFO]${NC} $1"
|
|
}
|
|
|
|
log_warn() {
|
|
echo -e "${YELLOW}[WARN]${NC} $1"
|
|
}
|
|
|
|
log_error() {
|
|
echo -e "${RED}[ERROR]${NC} $1"
|
|
}
|
|
|
|
# 检查并构建项目
|
|
build_project() {
|
|
log_info "开始构建项目..."
|
|
|
|
# 检查 Maven 是否安装
|
|
if ! command -v mvn > /dev/null 2>&1; then
|
|
log_error "未找到Maven命令,请确保已安装Maven"
|
|
exit 1
|
|
fi
|
|
|
|
# 执行 Maven 构建
|
|
log_info "执行: mvn clean package -DskipTests"
|
|
if ! mvn clean package -DskipTests; then
|
|
log_error "项目构建失败"
|
|
exit 1
|
|
fi
|
|
|
|
# 检查 JAR 文件是否生成
|
|
if [ ! -f "$JAR_PATH" ]; then
|
|
log_error "项目构建失败,未找到JAR文件: $JAR_PATH"
|
|
log_error "请检查 Maven 构建输出"
|
|
exit 1
|
|
fi
|
|
|
|
log_info "✅ 项目构建成功: $JAR_PATH"
|
|
log_info "文件大小: $(ls -lh $JAR_PATH | awk '{print $5}')"
|
|
}
|
|
|
|
# 检查 jar 文件是否存在
|
|
check_jar() {
|
|
if [ ! -f "$JAR_PATH" ]; then
|
|
log_error "JAR 文件不存在: $JAR_PATH"
|
|
log_info "请先执行打包命令: mvn clean package"
|
|
exit 1
|
|
fi
|
|
log_info "JAR 文件检查通过: $JAR_PATH"
|
|
}
|
|
|
|
# 创建日志目录
|
|
create_log_dir() {
|
|
if [ ! -d "$LOG_DIR" ]; then
|
|
log_info "创建日志目录: $LOG_DIR"
|
|
mkdir -p "$LOG_DIR"
|
|
fi
|
|
}
|
|
|
|
# 本地部署 - 停止旧服务
|
|
stop_local_service() {
|
|
if [ -f "$PID_FILE" ]; then
|
|
PID=$(cat "$PID_FILE")
|
|
if ps -p "$PID" > /dev/null 2>&1; then
|
|
log_info "停止旧服务 (PID: $PID)"
|
|
kill "$PID"
|
|
|
|
# 等待服务停止
|
|
for i in {1..30}; do
|
|
if ! ps -p "$PID" > /dev/null 2>&1; then
|
|
log_info "服务已停止"
|
|
break
|
|
fi
|
|
sleep 1
|
|
done
|
|
|
|
# 强制停止
|
|
if ps -p "$PID" > /dev/null 2>&1; then
|
|
log_warn "强制停止服务 (PID: $PID)"
|
|
kill -9 "$PID"
|
|
fi
|
|
else
|
|
log_warn "PID 文件存在但进程不存在,清理 PID 文件"
|
|
fi
|
|
rm -f "$PID_FILE"
|
|
else
|
|
log_info "没有找到 PID 文件,服务可能未运行"
|
|
fi
|
|
}
|
|
|
|
# 本地部署 - 启动新服务
|
|
start_local_service() {
|
|
log_info "启动本地服务..."
|
|
|
|
# 启动命令
|
|
nohup java $JAVA_OPTS \
|
|
-Dspring.profiles.active=$SPRING_PROFILE \
|
|
-Dlogging.file.path=$LOG_DIR \
|
|
-Dlogging.file.name=$LOG_DIR/application.log \
|
|
-jar "$JAR_PATH" \
|
|
> "$LOG_DIR/startup.log" 2>&1 &
|
|
|
|
# 保存 PID
|
|
echo $! > "$PID_FILE"
|
|
|
|
log_info "服务启动中,PID: $(cat $PID_FILE)"
|
|
log_info "启动日志: $LOG_DIR/startup.log"
|
|
log_info "应用日志: $LOG_DIR/application.log"
|
|
}
|
|
|
|
# 远程部署 - 上传文件到服务器
|
|
deploy_to_remote() {
|
|
log_info "开始远程部署到 $REMOTE_HOST..."
|
|
|
|
# 检查并构建项目
|
|
build_project
|
|
|
|
# 检查 jar 文件
|
|
check_jar
|
|
|
|
# 创建远程目录
|
|
log_info "创建远程目录..."
|
|
if ! ssh $REMOTE_USER@$REMOTE_HOST "mkdir -p $REMOTE_DIR"; then
|
|
log_error "创建远程目录失败: $REMOTE_DIR"
|
|
exit 1
|
|
fi
|
|
if ! ssh $REMOTE_USER@$REMOTE_HOST "mkdir -p $REMOTE_LOG_DIR"; then
|
|
log_error "创建远程日志目录失败: $REMOTE_LOG_DIR"
|
|
exit 1
|
|
fi
|
|
|
|
# 上传 jar 文件并重命名
|
|
log_info "上传 JAR 文件到远程服务器..."
|
|
log_info "本地文件: $JAR_PATH"
|
|
log_info "远程路径: $REMOTE_USER@$REMOTE_HOST:$REMOTE_DIR/$REMOTE_JAR_NAME"
|
|
|
|
if ! scp "$JAR_PATH" $REMOTE_USER@$REMOTE_HOST:$REMOTE_DIR/$REMOTE_JAR_NAME; then
|
|
log_error "上传 JAR 文件失败"
|
|
log_error "请检查:"
|
|
log_error " 1. SSH 连接是否正常: ssh $REMOTE_USER@$REMOTE_HOST 'ls -la $REMOTE_DIR'"
|
|
log_error " 2. 本地文件是否存在: ls -la $JAR_PATH"
|
|
log_error " 3. 远程目录权限: ssh $REMOTE_USER@$REMOTE_HOST 'ls -la $REMOTE_DIR'"
|
|
exit 1
|
|
fi
|
|
log_info "✅ JAR 文件上传成功"
|
|
|
|
# 验证远程文件
|
|
log_info "验证远程文件..."
|
|
if ! ssh $REMOTE_USER@$REMOTE_HOST "ls -lh $REMOTE_DIR/$REMOTE_JAR_NAME"; then
|
|
log_error "远程文件验证失败"
|
|
exit 1
|
|
fi
|
|
|
|
# 上传部署脚本
|
|
log_info "上传部署脚本到远程服务器..."
|
|
if ! scp "./deploy-server.sh" $REMOTE_USER@$REMOTE_HOST:$REMOTE_DIR/; then
|
|
log_error "上传部署脚本失败"
|
|
exit 1
|
|
fi
|
|
log_info "✅ 部署脚本上传成功"
|
|
|
|
# 设置权限
|
|
log_info "设置远程脚本权限..."
|
|
if ! ssh $REMOTE_USER@$REMOTE_HOST "chmod +x $REMOTE_DIR/deploy-server.sh"; then
|
|
log_error "设置脚本权限失败"
|
|
exit 1
|
|
fi
|
|
|
|
# 在远程服务器上执行部署
|
|
log_info "在远程服务器上执行部署..."
|
|
if ! ssh $REMOTE_USER@$REMOTE_HOST "cd $REMOTE_DIR && ./deploy-server.sh $SPRING_PROFILE"; then
|
|
log_error "远程部署脚本执行失败"
|
|
exit 1
|
|
fi
|
|
|
|
log_info "✅ 远程部署完成!"
|
|
show_remote_info
|
|
}
|
|
|
|
# 本地部署 - 检查服务状态
|
|
check_local_status() {
|
|
if [ -f "$PID_FILE" ]; then
|
|
PID=$(cat "$PID_FILE")
|
|
if ps -p "$PID" > /dev/null 2>&1; then
|
|
log_info "服务运行中 (PID: $PID)"
|
|
return 0
|
|
else
|
|
log_error "PID 文件存在但进程不存在"
|
|
return 1
|
|
fi
|
|
else
|
|
log_error "PID 文件不存在,服务未运行"
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
# 本地部署 - 等待服务启动
|
|
wait_for_local_startup() {
|
|
log_info "等待服务启动..."
|
|
for i in {1..60}; do
|
|
if check_local_status > /dev/null 2>&1; then
|
|
# 检查端口是否监听(使用 19089 端口)
|
|
if netstat -tlnp 2>/dev/null | grep -q ":19089.*LISTEN"; then
|
|
log_info "服务启动成功!"
|
|
return 0
|
|
fi
|
|
fi
|
|
sleep 2
|
|
done
|
|
|
|
log_error "服务启动超时,请检查日志: $LOG_DIR/startup.log"
|
|
return 1
|
|
}
|
|
|
|
# 本地部署 - 显示服务信息
|
|
show_local_info() {
|
|
log_info "=== 本地服务信息 ==="
|
|
log_info "应用名称: $APP_NAME"
|
|
log_info "JAR 文件: $JAR_PATH"
|
|
log_info "日志目录: $LOG_DIR"
|
|
log_info "PID 文件: $PID_FILE"
|
|
log_info "Java 参数: $JAVA_OPTS"
|
|
log_info "Spring Profile: $SPRING_PROFILE"
|
|
|
|
if check_local_status > /dev/null 2>&1; then
|
|
PID=$(cat "$PID_FILE")
|
|
log_info "服务状态: 运行中 (PID: $PID)"
|
|
|
|
# 显示内存使用情况
|
|
if command -v jstat > /dev/null 2>&1; then
|
|
log_info "内存使用情况:"
|
|
jstat -gc "$PID" | head -2
|
|
fi
|
|
else
|
|
log_info "服务状态: 未运行"
|
|
fi
|
|
}
|
|
|
|
# 远程部署 - 显示服务信息
|
|
show_remote_info() {
|
|
log_info "=== 远程服务信息 ==="
|
|
log_info "服务器地址: $REMOTE_HOST"
|
|
log_info "部署目录: $REMOTE_DIR"
|
|
log_info "日志目录: $REMOTE_LOG_DIR"
|
|
log_info "Spring Profile: $SPRING_PROFILE"
|
|
|
|
# 检查远程服务状态
|
|
log_info "检查远程服务状态..."
|
|
ssh $REMOTE_USER@$REMOTE_HOST "ps aux | grep $JAR_NAME | grep -v grep" || log_info "远程服务未运行"
|
|
}
|
|
|
|
# 本地部署 - 主函数
|
|
local_deploy() {
|
|
log_info "开始本地部署 $APP_NAME 服务..."
|
|
|
|
# 检查并构建项目
|
|
build_project
|
|
|
|
# 检查 jar 文件
|
|
check_jar
|
|
|
|
# 创建日志目录
|
|
create_log_dir
|
|
|
|
# 停止旧服务
|
|
stop_local_service
|
|
|
|
# 启动新服务
|
|
start_local_service
|
|
|
|
# 等待启动
|
|
if wait_for_local_startup; then
|
|
log_info "本地部署成功!"
|
|
show_local_info
|
|
else
|
|
log_error "本地部署失败!"
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
# 处理命令行参数
|
|
case "${1:-deploy}" in
|
|
"deploy")
|
|
local_deploy
|
|
;;
|
|
"remote")
|
|
deploy_to_remote
|
|
;;
|
|
"build")
|
|
build_project
|
|
;;
|
|
"start")
|
|
# 检查并构建项目
|
|
build_project
|
|
check_jar
|
|
create_log_dir
|
|
start_local_service
|
|
wait_for_local_startup
|
|
;;
|
|
"stop")
|
|
stop_local_service
|
|
;;
|
|
"restart")
|
|
stop_local_service
|
|
sleep 2
|
|
# 检查并构建项目
|
|
build_project
|
|
check_jar
|
|
create_log_dir
|
|
start_local_service
|
|
wait_for_local_startup
|
|
;;
|
|
"status")
|
|
show_local_info
|
|
;;
|
|
"remote-status")
|
|
show_remote_info
|
|
;;
|
|
"logs")
|
|
if [ -f "$LOG_DIR/application.log" ]; then
|
|
tail -f "$LOG_DIR/application.log"
|
|
else
|
|
log_error "日志文件不存在: $LOG_DIR/application.log"
|
|
fi
|
|
;;
|
|
*)
|
|
echo "用法: $0 {deploy|remote|build|start|stop|restart|status|remote-status|logs}"
|
|
echo " deploy - 本地部署服务(默认)"
|
|
echo " remote - 远程部署到服务器"
|
|
echo " build - 构建项目"
|
|
echo " start - 启动本地服务"
|
|
echo " stop - 停止本地服务"
|
|
echo " restart - 重启本地服务"
|
|
echo " status - 查看本地服务状态"
|
|
echo " remote-status - 查看远程服务状态"
|
|
echo " logs - 查看本地实时日志"
|
|
exit 1
|
|
;;
|
|
esac |