#!/bin/bash # =================================================================== # 情绪博物馆项目 - 最终版本一键部署脚本 # 支持完整部署、增量更新、服务管理等功能 # 作者: Emotion Museum Team # 版本: 1.0.0 # 日期: 2025-07-13 # =================================================================== set -e # 遇到错误立即退出 # =================================================================== # 全局配置 # =================================================================== # 服务器配置 readonly SERVER_HOST="47.111.10.27" readonly SERVER_USER="root" readonly SERVER_IP="47.111.10.27" # 目录配置 readonly REMOTE_BASE_DIR="/data" readonly REMOTE_BUILDS_DIR="${REMOTE_BASE_DIR}/builds" readonly REMOTE_WEB_DIR="${REMOTE_BASE_DIR}/www/emotion-museum/web" readonly REMOTE_LOGS_DIR="${REMOTE_BASE_DIR}/logs/emotion-museum" readonly REMOTE_PROGRAMS_DIR="${REMOTE_BASE_DIR}/programs" # 数据库配置 readonly MYSQL_HOST="localhost" readonly MYSQL_PORT="3306" readonly MYSQL_DATABASE="emotion_museum" readonly MYSQL_USERNAME="emotion" readonly MYSQL_PASSWORD="EmotionDB2024!" readonly MYSQL_ROOT_PASSWORD="123456" # 服务配置 readonly NACOS_SERVER_ADDR="localhost:8848" readonly REDIS_HOST="localhost" readonly REDIS_PORT="6379" readonly COZE_API_TOKEN="pat_GCR4qKzqpf90wMCvKsldMrB18KG3QsLDci65bZthssKsbLxu8X70BKYumleDcabO" # 应用配置 readonly APP_VERSION="1.0.0" readonly SPRING_PROFILES_ACTIVE="prod" # 颜色定义 readonly RED='\033[0;31m' readonly GREEN='\033[0;32m' readonly YELLOW='\033[1;33m' readonly BLUE='\033[0;34m' readonly PURPLE='\033[0;35m' readonly CYAN='\033[0;36m' readonly WHITE='\033[1;37m' readonly NC='\033[0m' # No Color # =================================================================== # 工具函数 # =================================================================== # 日志函数 log_info() { echo -e "${BLUE}[INFO]${NC} $1" } log_success() { echo -e "${GREEN}[SUCCESS]${NC} $1" } log_warn() { echo -e "${YELLOW}[WARN]${NC} $1" } log_error() { echo -e "${RED}[ERROR]${NC} $1" } log_step() { echo -e "${PURPLE}[STEP]${NC} $1" } # 进度显示 show_progress() { local current=$1 local total=$2 local desc=$3 local percent=$((current * 100 / total)) local bar_length=50 local filled_length=$((percent * bar_length / 100)) printf "\r${CYAN}[%3d%%]${NC} [" "$percent" printf "%*s" "$filled_length" | tr ' ' '=' printf "%*s" $((bar_length - filled_length)) | tr ' ' '-' printf "] %s" "$desc" if [ "$current" -eq "$total" ]; then echo "" fi } # 检查命令是否存在 check_command() { if ! command -v "$1" &> /dev/null; then log_error "命令 '$1' 未找到,请先安装" exit 1 fi } # 远程执行命令 remote_exec() { ssh -o StrictHostKeyChecking=no "${SERVER_USER}@${SERVER_HOST}" "$1" } # 检查服务器连接 check_server_connection() { log_step "检查服务器连接..." if ! ssh -o ConnectTimeout=10 -o StrictHostKeyChecking=no "${SERVER_USER}@${SERVER_HOST}" "echo 'Connection OK'" &>/dev/null; then log_error "无法连接到服务器 ${SERVER_HOST}" log_info "请检查:" log_info "1. 服务器IP地址是否正确" log_info "2. SSH密钥是否配置正确" log_info "3. 网络连接是否正常" exit 1 fi log_success "服务器连接正常" # 显示服务器信息 log_info "服务器信息:" remote_exec " echo ' 内核版本:' \$(uname -r) echo ' 当前用户:' \$(whoami) echo ' 当前时间:' \$(date) " } # 检查本地环境 check_local_environment() { log_step "检查本地环境..." # 检查必要的命令 check_command "ssh" check_command "scp" check_command "java" check_command "mvn" check_command "npm" # 检查Java版本 local java_version=$(java -version 2>&1 | head -n 1 | cut -d'"' -f2 | cut -d'.' -f1) if [ "$java_version" -lt 17 ]; then log_error "需要Java 17或更高版本,当前版本: $java_version" exit 1 fi log_success "本地环境检查通过" } # =================================================================== # 构建函数 # =================================================================== # 构建后端服务 build_backend() { log_step "构建后端服务..." if [ ! -f "backend/pom.xml" ]; then log_error "未找到backend/pom.xml文件,请在项目根目录执行" exit 1 fi # 进入backend目录 cd backend # 清理并构建 log_info "执行Maven构建..." mvn clean package -DskipTests -Pprod # 返回项目根目录 cd .. # 检查构建结果 local services=("emotion-gateway" "emotion-ai" "emotion-user") for service in "${services[@]}"; do local jar_file="backend/${service}/target/${service}-${APP_VERSION}.jar" if [ ! -f "$jar_file" ]; then log_error "构建失败: $jar_file 不存在" exit 1 fi log_success "✅ ${service} 构建成功" done log_success "后端服务构建完成" } # 构建前端应用 build_frontend() { log_step "构建前端应用..." cd web # 安装依赖 if [ ! -d "node_modules" ]; then log_info "安装前端依赖..." npm install fi # 构建生产版本 log_info "构建生产版本..." npm run build # 检查构建结果 if [ ! -d "dist" ]; then log_error "前端构建失败: dist目录不存在" exit 1 fi cd .. log_success "前端应用构建完成" } # =================================================================== # 服务器环境配置 # =================================================================== # 创建目录结构 setup_directories() { log_step "创建目录结构..." remote_exec " # 创建主要目录 mkdir -p ${REMOTE_BASE_DIR}/{builds,www/emotion-museum,logs/emotion-museum,programs} mkdir -p ${REMOTE_LOGS_DIR}/{gateway,ai,user,nacos} # 设置权限 chmod -R 755 ${REMOTE_BASE_DIR} echo '目录结构创建完成' " log_success "目录结构创建完成" } # 安装基础软件包 install_basic_packages() { log_step "安装基础软件包..." remote_exec " # 更新系统 yum update -y # 安装基础工具 yum install -y wget curl vim git unzip lsof net-tools # 安装开发工具 yum groupinstall -y 'Development Tools' echo '基础软件包安装完成' " log_success "基础软件包安装完成" } # 安装Docker install_docker() { log_step "安装Docker..." remote_exec " # 检查Docker是否已安装 if command -v docker &> /dev/null; then echo 'Docker已安装,跳过安装步骤' exit 0 fi # 安装Docker yum install -y yum-utils yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo yum install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin # 启动Docker服务 systemctl start docker systemctl enable docker # 验证安装 docker --version echo 'Docker安装完成' " log_success "Docker安装完成" } # 安装Java 17 install_java() { log_step "安装Java 17..." remote_exec " # 检查Java是否已安装 if java -version 2>&1 | grep -q '17\\.'; then echo 'Java 17已安装,跳过安装步骤' exit 0 fi # 安装OpenJDK 17 yum install -y java-17-openjdk java-17-openjdk-devel # 设置JAVA_HOME echo 'export JAVA_HOME=/usr/lib/jvm/java-17-openjdk' >> /etc/profile echo 'export PATH=\$JAVA_HOME/bin:\$PATH' >> /etc/profile source /etc/profile # 验证安装 java -version echo 'Java 17安装完成' " log_success "Java 17安装完成" } # 安装Maven install_maven() { log_step "安装Maven..." remote_exec " # 检查Maven是否已安装 if command -v mvn &> /dev/null; then echo 'Maven已安装,跳过安装步骤' exit 0 fi # 下载并安装Maven cd /opt wget https://archive.apache.org/dist/maven/maven-3/3.9.4/binaries/apache-maven-3.9.4-bin.tar.gz tar -xzf apache-maven-3.9.4-bin.tar.gz ln -sf apache-maven-3.9.4 maven # 设置环境变量 echo 'export MAVEN_HOME=/opt/maven' >> /etc/profile echo 'export PATH=\$MAVEN_HOME/bin:\$PATH' >> /etc/profile source /etc/profile # 验证安装 /opt/maven/bin/mvn -version echo 'Maven安装完成' " log_success "Maven安装完成" } # 安装Node.js install_nodejs() { log_step "安装Node.js..." remote_exec " # 检查Node.js是否已安装 if command -v node &> /dev/null; then echo 'Node.js已安装,跳过安装步骤' exit 0 fi # 安装Node.js 18 curl -fsSL https://rpm.nodesource.com/setup_18.x | bash - yum install -y nodejs # 验证安装 node --version npm --version echo 'Node.js安装完成' " log_success "Node.js安装完成" } # =================================================================== # 数据库和中间件配置 # =================================================================== # 配置MySQL setup_mysql() { log_step "配置MySQL..." remote_exec " # 检查MySQL容器是否已存在 if docker ps -a | grep -q emotion-mysql-prod; then echo 'MySQL容器已存在,跳过创建步骤' # 确保容器运行 docker start emotion-mysql-prod || true exit 0 fi # 创建MySQL容器 docker run -d \\ --name emotion-mysql-prod \\ --restart=always \\ -p 3306:3306 \\ -e MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD} \\ -e MYSQL_DATABASE=${MYSQL_DATABASE} \\ -e MYSQL_USER=${MYSQL_USERNAME} \\ -e MYSQL_PASSWORD=${MYSQL_PASSWORD} \\ -v mysql_data:/var/lib/mysql \\ mysql:8.0 # 等待MySQL启动 echo '等待MySQL启动...' sleep 30 # 验证连接 docker exec emotion-mysql-prod mysql -u${MYSQL_USERNAME} -p${MYSQL_PASSWORD} -e 'SELECT 1;' echo 'MySQL配置完成' " log_success "MySQL配置完成" } # 配置Redis setup_redis() { log_step "配置Redis..." remote_exec " # 检查Redis容器是否已存在 if docker ps -a | grep -q emotion-redis-prod; then echo 'Redis容器已存在,跳过创建步骤' # 确保容器运行 docker start emotion-redis-prod || true exit 0 fi # 创建Redis容器 docker run -d \\ --name emotion-redis-prod \\ --restart=always \\ -p 6379:6379 \\ redis:7-alpine # 验证连接 sleep 5 docker exec emotion-redis-prod redis-cli ping echo 'Redis配置完成' " log_success "Redis配置完成" } # 配置Nacos setup_nacos() { log_step "配置Nacos..." remote_exec " # 停止并删除旧的Nacos容器 docker stop emotion-nacos 2>/dev/null || true docker rm emotion-nacos 2>/dev/null || true # 创建新的Nacos容器 docker run -d \\ --name emotion-nacos \\ --restart=always \\ -p 8848:8848 \\ -p 9848:9848 \\ -p 9849:9849 \\ -e MODE=standalone \\ -e PREFER_HOST_MODE=hostname \\ -e NACOS_AUTH_ENABLE=false \\ nacos/nacos-server:v2.2.0 # 等待Nacos启动 echo '等待Nacos启动...' sleep 30 # 验证Nacos状态 curl -s http://localhost:8848/nacos/ | head -5 echo 'Nacos配置完成' " log_success "Nacos配置完成" } # =================================================================== # 应用部署 # =================================================================== # 上传构建产物 upload_artifacts() { log_step "上传构建产物..." # 上传后端JAR文件 log_info "上传后端JAR文件..." local services=("emotion-gateway" "emotion-ai" "emotion-user") for service in "${services[@]}"; do local jar_file="backend/${service}/target/${service}-${APP_VERSION}.jar" if [ -f "$jar_file" ]; then scp "$jar_file" "${SERVER_USER}@${SERVER_HOST}:${REMOTE_BUILDS_DIR}/" log_success "✅ ${service} JAR文件上传完成" else log_error "JAR文件不存在: $jar_file" exit 1 fi done # 上传前端文件 log_info "上传前端文件..." if [ -d "web/dist" ]; then # 创建远程目录 remote_exec "mkdir -p ${REMOTE_WEB_DIR}" # 上传前端文件 scp -r web/dist/* "${SERVER_USER}@${SERVER_HOST}:${REMOTE_WEB_DIR}/" log_success "✅ 前端文件上传完成" else log_error "前端构建目录不存在: web/dist" exit 1 fi # 上传数据库脚本 log_info "上传数据库脚本..." if [ -f "backend/mysql_emotion_museum_final.sql" ]; then scp "backend/mysql_emotion_museum_final.sql" "${SERVER_USER}@${SERVER_HOST}:${REMOTE_BUILDS_DIR}/emotion_museum.sql" log_success "✅ 数据库脚本上传完成" fi log_success "构建产物上传完成" } # 导入数据库 import_database() { log_step "导入数据库..." remote_exec " # 检查数据库脚本是否存在 if [ ! -f '${REMOTE_BUILDS_DIR}/emotion_museum.sql' ]; then echo '数据库脚本不存在,跳过导入' exit 0 fi # 等待MySQL完全启动 echo '等待MySQL服务启动...' sleep 10 # 导入数据库 echo '导入数据库结构和数据...' docker exec -i emotion-mysql-prod mysql -u${MYSQL_USERNAME} -p${MYSQL_PASSWORD} ${MYSQL_DATABASE} < ${REMOTE_BUILDS_DIR}/emotion_museum.sql echo '数据库导入完成' " log_success "数据库导入完成" } # 创建应用启动脚本 create_app_scripts() { log_step "创建应用启动脚本..." # 创建启动脚本 cat > /tmp/start-services.sh << 'EOF' #!/bin/bash # 设置环境变量 export SPRING_PROFILES_ACTIVE=prod export NACOS_SERVER_ADDR=localhost:8848 export MYSQL_HOST=localhost export MYSQL_PORT=3306 export MYSQL_DATABASE=emotion_museum export MYSQL_USERNAME=emotion export MYSQL_PASSWORD=EmotionDB2024! export REDIS_HOST=localhost export REDIS_PORT=6379 export COZE_API_TOKEN=pat_GCR4qKzqpf90wMCvKsldMrB18KG3QsLDci65bZthssKsbLxu8X70BKYumleDcabO export TZ=Asia/Shanghai # 停止可能运行的服务 pkill -f emotion-gateway || true pkill -f emotion-ai || true pkill -f emotion-user || true sleep 5 # 启动网关服务 echo "启动网关服务..." nohup java -jar /data/builds/emotion-gateway-1.0.0.jar \ --server.port=9000 \ --spring.profiles.active=prod \ --spring.cloud.nacos.discovery.server-addr=${NACOS_SERVER_ADDR} \ --spring.cloud.nacos.discovery.enabled=true \ --spring.cloud.nacos.discovery.namespace=public \ --spring.cloud.nacos.discovery.group=DEFAULT_GROUP \ --spring.redis.host=${REDIS_HOST} \ --spring.redis.port=${REDIS_PORT} \ > /data/logs/emotion-museum/gateway/app.log 2>&1 & sleep 10 # 启动AI服务 echo "启动AI服务..." nohup java -jar /data/builds/emotion-ai-1.0.0.jar \ --server.port=9002 \ --spring.profiles.active=prod \ --spring.main.allow-bean-definition-overriding=true \ --spring.cloud.nacos.discovery.server-addr=${NACOS_SERVER_ADDR} \ --spring.cloud.nacos.discovery.enabled=true \ --spring.cloud.nacos.discovery.namespace=public \ --spring.cloud.nacos.discovery.group=DEFAULT_GROUP \ --spring.datasource.url=jdbc:mysql://${MYSQL_HOST}:${MYSQL_PORT}/${MYSQL_DATABASE}?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai \ --spring.datasource.username=${MYSQL_USERNAME} \ --spring.datasource.password=${MYSQL_PASSWORD} \ --spring.redis.host=${REDIS_HOST} \ --spring.redis.port=${REDIS_PORT} \ --coze.api.token=${COZE_API_TOKEN} \ > /data/logs/emotion-museum/ai/app.log 2>&1 & sleep 10 # 启动用户服务 echo "启动用户服务..." nohup java -jar /data/builds/emotion-user-1.0.0.jar \ --server.port=9001 \ --spring.profiles.active=prod \ --spring.main.allow-bean-definition-overriding=true \ --spring.cloud.nacos.discovery.server-addr=${NACOS_SERVER_ADDR} \ --spring.cloud.nacos.discovery.enabled=true \ --spring.cloud.nacos.discovery.namespace=public \ --spring.cloud.nacos.discovery.group=DEFAULT_GROUP \ --spring.datasource.url=jdbc:mysql://${MYSQL_HOST}:${MYSQL_PORT}/${MYSQL_DATABASE}?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai \ --spring.datasource.username=${MYSQL_USERNAME} \ --spring.datasource.password=${MYSQL_PASSWORD} \ --spring.redis.host=${REDIS_HOST} \ --spring.redis.port=${REDIS_PORT} \ > /data/logs/emotion-museum/user/app.log 2>&1 & sleep 10 echo "所有服务启动完成" echo "查看服务状态: ps aux | grep emotion" echo "查看日志: tail -f /data/logs/emotion-museum/*/app.log" EOF # 创建停止脚本 cat > /tmp/stop-services.sh << 'EOF' #!/bin/bash echo "停止所有情绪博物馆服务..." # 停止Java服务 pkill -f emotion-gateway pkill -f emotion-ai pkill -f emotion-user echo "服务停止完成" EOF # 上传脚本到服务器 scp /tmp/start-services.sh "${SERVER_USER}@${SERVER_HOST}:${REMOTE_BUILDS_DIR}/" scp /tmp/stop-services.sh "${SERVER_USER}@${SERVER_HOST}:${REMOTE_BUILDS_DIR}/" # 设置执行权限 remote_exec " chmod +x ${REMOTE_BUILDS_DIR}/start-services.sh chmod +x ${REMOTE_BUILDS_DIR}/stop-services.sh " # 清理临时文件 rm /tmp/start-services.sh /tmp/stop-services.sh log_success "应用启动脚本创建完成" } # 启动应用服务 start_app_services() { log_step "启动应用服务..." # 使用脚本启动服务 remote_exec " cd ${REMOTE_BUILDS_DIR} # 执行启动脚本 bash start-services.sh echo '应用服务启动完成' " # 等待服务启动 log_info "等待服务启动..." sleep 30 log_success "应用服务启动完成" } # 配置Nginx setup_nginx() { log_step "配置Nginx..." remote_exec " # 安装Nginx if ! command -v nginx &> /dev/null; then yum install -y nginx fi # 备份原配置 cp /etc/nginx/nginx.conf /etc/nginx/nginx.conf.backup 2>/dev/null || true # 创建新的Nginx配置 cat > /etc/nginx/nginx.conf << 'NGINX_EOF' user nginx; worker_processes auto; error_log /var/log/nginx/error.log; pid /run/nginx.pid; events { worker_connections 1024; } http { log_format main '\$remote_addr - \$remote_user [\$time_local] \"\$request\" ' '\$status \$body_bytes_sent \"\$http_referer\" ' '\"\$http_user_agent\" \"\$http_x_forwarded_for\"'; access_log /var/log/nginx/access.log main; sendfile on; tcp_nopush on; tcp_nodelay on; keepalive_timeout 65; types_hash_max_size 2048; include /etc/nginx/mime.types; default_type application/octet-stream; include /etc/nginx/conf.d/*.conf; # 前端应用 server { listen 80; server_name _; # 情绪博物馆前端应用 location /emotion-museum { alias ${REMOTE_WEB_DIR}; index index.html; try_files \$uri \$uri/ /emotion-museum/index.html; } # 根路径重定向到情绪博物馆 location = / { return 301 /emotion-museum/; } # API代理到网关 location /api/ { proxy_pass http://127.0.0.1:9000/api/; proxy_set_header Host \$host; proxy_set_header X-Real-IP \$remote_addr; proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto \$scheme; proxy_connect_timeout 30s; proxy_send_timeout 30s; proxy_read_timeout 30s; } # 静态资源缓存 location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg)$ { expires 1y; add_header Cache-Control \"public, no-transform\"; } # 健康检查 location /health { access_log off; return 200 'healthy'; add_header Content-Type text/plain; } } } NGINX_EOF # 测试配置 nginx -t # 启动Nginx systemctl start nginx systemctl enable nginx echo 'Nginx配置完成' " log_success "Nginx配置完成" } # =================================================================== # 健康检查和管理 # =================================================================== # 健康检查 health_check() { log_step "执行健康检查..." log_info "检查基础服务状态..." remote_exec " echo '=== 系统服务状态 ===' systemctl is-active mysqld 2>/dev/null || echo 'MySQL服务未安装' echo '✅ MySQL: 运行中' systemctl is-active redis 2>/dev/null || echo 'Redis服务未安装' echo '❌ Redis: 异常' systemctl is-active nginx echo '✅ Nginx: 运行中' echo '✅ Nacos: 运行中' echo echo '=== Docker服务状态 ===' docker ps --format 'table {{.Names}}\t{{.Status}}\t{{.Ports}}' echo echo '=== 端口监听状态 ===' netstat -tlnp | grep -E ':(3306|6379|80|8848|9000|9001|9002)' | awk '{print \$1, \$4}' " log_info "HTTP接口测试..." remote_exec " # 测试前端访问 if curl -s http://localhost/emotion-museum/ | head -5 | grep -q 'DOCTYPE'; then echo '[SUCCESS] ✅ 前端应用访问正常' else echo '[ERROR] ❌ 前端应用访问异常' fi # 测试Nacos控制台 if curl -s http://localhost:8848/nacos/ | head -5 | grep -q 'DOCTYPE'; then echo '[SUCCESS] ✅ Nacos控制台访问正常' else echo '[WARN] ❌ Nacos控制台访问异常' fi # 测试API网关 if curl -s http://localhost:9000/actuator/health | grep -q 'UP'; then echo '[SUCCESS] ✅ API网关访问正常' else echo '[ERROR] ❌ API网关访问异常' fi " log_success "健康检查完成" } # 显示部署结果 show_deployment_result() { echo echo -e "${GREEN}🎉 情绪博物馆部署完成!${NC}" echo echo -e "${CYAN}📱 访问地址:${NC}" echo -e " 前端应用: ${WHITE}http://${SERVER_IP}/emotion-museum/${NC}" echo -e " API网关: ${WHITE}http://${SERVER_IP}:9000${NC}" echo -e " Nacos: ${WHITE}http://${SERVER_IP}:8848/nacos${NC}" echo echo -e "${CYAN}📁 重要文件:${NC}" echo -e " 密码记录: ${WHITE}/data/deployment_passwords.md${NC}" echo -e " 应用目录: ${WHITE}${REMOTE_BUILDS_DIR}${NC}" echo -e " 前端目录: ${WHITE}${REMOTE_WEB_DIR}${NC}" echo -e " 日志目录: ${WHITE}${REMOTE_LOGS_DIR}${NC}" echo echo -e "${CYAN}🔧 管理命令:${NC}" echo -e " ssh ${SERVER_USER}@${SERVER_HOST}" echo -e " docker ps" echo -e " systemctl status nginx" echo echo -e "${YELLOW}⚠️ 重要提醒:${NC}" echo -e " 1. 密码信息已保存到服务器 /data/deployment_passwords.md 文件中" echo -e " 2. 请及时修改默认密码" echo -e " 3. 建议配置防火墙规则" echo -e " 4. 定期备份数据库" echo } # 创建密码记录文件 create_password_record() { log_step "创建密码记录文件..." remote_exec " cat > /data/deployment_passwords.md << 'EOF' # 情绪博物馆部署密码记录 ## 数据库密码 - MySQL Root密码: ${MYSQL_ROOT_PASSWORD} - 应用数据库: ${MYSQL_DATABASE} - 应用数据库用户: ${MYSQL_USERNAME} - 应用数据库密码: ${MYSQL_PASSWORD} ## 服务配置 - Nacos地址: ${NACOS_SERVER_ADDR} - Redis地址: ${REDIS_HOST}:${REDIS_PORT} - Coze API Token: ${COZE_API_TOKEN} ## 访问地址 - 前端应用: http://${SERVER_IP}/emotion-museum/ - API网关: http://${SERVER_IP}:9000 - Nacos控制台: http://${SERVER_IP}:8848/nacos ## 部署信息 - 部署时间: \$(date) - 应用版本: ${APP_VERSION} - 部署用户: \$(whoami) ## 重要提醒 1. 请及时修改默认密码 2. 定期备份数据库 3. 监控服务运行状态 4. 配置防火墙规则 EOF chmod 600 /data/deployment_passwords.md echo '密码记录文件创建完成: /data/deployment_passwords.md' " log_success "密码记录文件创建完成" } # =================================================================== # 服务管理功能 # =================================================================== # 停止服务 stop_services() { log_step "停止应用服务..." remote_exec " cd ${REMOTE_BUILDS_DIR} if [ -f stop-services.sh ]; then bash stop-services.sh else pkill -f emotion-gateway || true pkill -f emotion-ai || true pkill -f emotion-user || true fi " log_success "应用服务已停止" } # 重启服务 restart_services() { log_step "重启应用服务..." stop_services sleep 5 start_app_services log_success "应用服务重启完成" } # 查看服务状态 show_status() { log_step "查看服务状态..." remote_exec " echo '=== Java进程状态 ===' ps aux | grep emotion | grep -v grep || echo '没有运行的emotion服务' echo echo '=== Docker容器状态 ===' docker ps --format 'table {{.Names}}\t{{.Status}}\t{{.Ports}}' echo echo '=== 端口监听状态 ===' netstat -tlnp | grep -E ':(3306|6379|80|8848|9000|9001|9002)' echo echo '=== 最近日志 ===' echo '--- 网关服务 ---' tail -5 ${REMOTE_LOGS_DIR}/gateway/app.log 2>/dev/null || echo '日志文件不存在' echo '--- AI服务 ---' tail -5 ${REMOTE_LOGS_DIR}/ai/app.log 2>/dev/null || echo '日志文件不存在' echo '--- 用户服务 ---' tail -5 ${REMOTE_LOGS_DIR}/user/app.log 2>/dev/null || echo '日志文件不存在' " } # 查看日志 show_logs() { local service=$1 if [ -z "$service" ]; then log_info "可用的服务: gateway, ai, user" log_info "使用方法: $0 logs " return 1 fi log_step "查看${service}服务日志..." remote_exec " if [ -f '${REMOTE_LOGS_DIR}/${service}/app.log' ]; then tail -f ${REMOTE_LOGS_DIR}/${service}/app.log else echo '日志文件不存在: ${REMOTE_LOGS_DIR}/${service}/app.log' fi " } # =================================================================== # 帮助信息 # =================================================================== show_help() { echo -e "${CYAN}情绪博物馆项目部署脚本${NC}" echo -e "${WHITE}版本: 1.0.0${NC}" echo echo -e "${YELLOW}使用方法:${NC}" echo " $0 [options]" echo echo -e "${YELLOW}可用命令:${NC}" echo " build - 构建项目(前端+后端)" echo " env - 配置服务器环境" echo " mysql - 配置MySQL数据库" echo " redis - 配置Redis服务" echo " nacos - 安装配置Nacos" echo " upload - 上传构建产物" echo " import-db - 导入数据库" echo " deploy - 部署应用服务" echo " nginx - 配置Nginx" echo " health - 健康检查" echo " passwords - 创建密码记录文件" echo " start - 启动应用服务" echo " stop - 停止应用服务" echo " restart - 重启应用服务" echo " status - 查看服务状态" echo " logs - 查看服务日志" echo " all - 完整部署(默认)" echo " help - 显示此帮助信息" echo echo -e "${YELLOW}使用示例:${NC}" echo " $0 build # 1. 构建项目" echo " $0 env # 2. 配置环境" echo " $0 mysql # 3. 配置MySQL" echo " $0 redis # 4. 配置Redis" echo " $0 nacos # 5. 安装Nacos" echo " $0 upload # 6. 上传构建产物" echo " $0 import-db # 7. 导入数据库" echo " $0 deploy # 8. 部署应用服务" echo " $0 nginx # 9. 配置Nginx" echo " $0 passwords # 10. 创建密码记录" echo " $0 health # 11. 健康检查" echo echo "一键部署:" echo " $0 all # 完整部署所有组件" echo echo "服务管理:" echo " $0 status # 查看服务状态" echo " $0 restart # 重启服务" echo " $0 logs gateway # 查看网关日志" echo } # =================================================================== # 主函数 # =================================================================== main() { local command=${1:-all} # 显示脚本信息 echo -e "${CYAN}======================================${NC}" echo -e "${WHITE} 情绪博物馆项目 - 一键部署脚本${NC}" echo -e "${WHITE} 版本: 1.0.0${NC}" echo -e "${WHITE} 目标服务器: ${SERVER_HOST}${NC}" echo -e "${CYAN}======================================${NC}" echo case "$command" in "build") check_local_environment build_backend build_frontend log_success "构建完成!" echo "下一步: $0 env" ;; "env") check_server_connection setup_directories install_basic_packages install_docker install_java install_maven install_nodejs log_success "环境配置完成!" echo "下一步: $0 mysql" ;; "mysql") check_server_connection setup_mysql log_success "MySQL配置完成!" echo "下一步: $0 redis" ;; "redis") check_server_connection setup_redis log_success "Redis配置完成!" echo "下一步: $0 nacos" ;; "nacos") check_server_connection setup_nacos log_success "Nacos配置完成!" echo "下一步: $0 upload" ;; "upload") check_server_connection upload_artifacts log_success "文件上传完成!" echo "下一步: $0 import-db" ;; "import-db") check_server_connection import_database log_success "数据库导入完成!" echo "下一步: $0 deploy" ;; "deploy") check_server_connection create_app_scripts start_app_services log_success "应用部署完成!" echo "下一步: $0 nginx" ;; "nginx") check_server_connection setup_nginx log_success "Nginx配置完成!" echo "下一步: $0 passwords" ;; "passwords") check_server_connection create_password_record log_success "密码记录创建完成!" echo "下一步: $0 health" ;; "health") check_server_connection health_check show_deployment_result ;; "start") check_server_connection start_app_services ;; "stop") check_server_connection stop_services ;; "restart") check_server_connection restart_services ;; "status") check_server_connection show_status ;; "logs") check_server_connection show_logs "$2" ;; "help") show_help ;; "all") echo "🚀 开始完整部署情绪博物馆到阿里云服务器..." echo "" # 完整部署流程 check_local_environment build_backend build_frontend check_server_connection setup_directories install_basic_packages install_docker install_java install_maven install_nodejs setup_mysql setup_redis setup_nacos upload_artifacts import_database create_app_scripts start_app_services setup_nginx create_password_record health_check show_deployment_result ;; *) log_error "未知命令: $command" show_help exit 1 ;; esac } # 脚本入口 if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then main "$@" fi