# 解班客项目部署和运维文档

## 📋 文档概述

本文档详细说明解班客项目的部署流程、运维管理和监控体系，涵盖开发、测试、生产环境的完整部署方案。

### 文档目标
- 建立标准化的部署流程
- 提供完整的运维管理方案
- 建立监控和告警体系
- 确保系统高可用性和稳定性

## 🏗️ 系统架构

### 整体架构图
```
┌─────────────────────────────────────────────────────────────┐
│                        负载均衡层                              │
│  ┌─────────────┐  ┌─────────────┐  ┌─────────────┐        │
│  │   Nginx     │  │   Nginx     │  │   Nginx     │        │
│  │  (主节点)    │  │  (备节点1)   │  │  (备节点2)   │        │
│  └─────────────┘  └─────────────┘  └─────────────┘        │
└─────────────────────────────────────────────────────────────┘
                              │
┌─────────────────────────────────────────────────────────────┐
│                        应用服务层                              │
│  ┌─────────────┐  ┌─────────────┐  ┌─────────────┐        │
│  │  Node.js    │  │  Node.js    │  │  Node.js    │        │
│  │   API-1     │  │   API-2     │  │   API-3     │        │
│  └─────────────┘  └─────────────┘  └─────────────┘        │
└─────────────────────────────────────────────────────────────┘
                              │
┌─────────────────────────────────────────────────────────────┐
│                        数据存储层                              │
│  ┌─────────────┐  ┌─────────────┐  ┌─────────────┐        │
│  │   MySQL     │  │    Redis    │  │   MinIO     │        │
│  │  (主从复制)  │  │   (集群)     │  │ (对象存储)   │        │
│  └─────────────┘  └─────────────┘  └─────────────┘        │
└─────────────────────────────────────────────────────────────┘
                              │
┌─────────────────────────────────────────────────────────────┐
│                        监控运维层                              │
│  ┌─────────────┐  ┌─────────────┐  ┌─────────────┐        │
│  │ Prometheus  │  │   Grafana   │  │  ELK Stack  │        │
│  │   (监控)     │  │  (可视化)    │  │   (日志)     │        │
│  └─────────────┘  └─────────────┘  └─────────────┘        │
└─────────────────────────────────────────────────────────────┘
```

### 技术栈选择
```yaml
# 技术栈配置
tech_stack:
  frontend:
    framework: "Vue 3"
    build_tool: "Vite"
    ui_library: "Element Plus"
    state_management: "Pinia"
    
  backend:
    runtime: "Node.js 18+"
    framework: "Express.js"
    orm: "Sequelize"
    authentication: "JWT"
    
  database:
    primary: "MySQL 8.0"
    cache: "Redis 7.0"
    search: "Elasticsearch 8.0"
    
  storage:
    object_storage: "MinIO"
    cdn: "阿里云CDN"
    
  infrastructure:
    container: "Docker"
    orchestration: "Docker Compose / Kubernetes"
    reverse_proxy: "Nginx"
    
  monitoring:
    metrics: "Prometheus"
    visualization: "Grafana"
    logging: "ELK Stack"
    alerting: "AlertManager"
```

## 🐳 容器化部署

### Docker配置

#### 前端Dockerfile
```dockerfile
# frontend/Dockerfile
FROM node:18-alpine AS builder

# 设置工作目录
WORKDIR /app

# 复制package文件
COPY package*.json ./

# 安装依赖
RUN npm ci --only=production

# 复制源代码
COPY . .

# 构建应用
RUN npm run build

# 生产环境镜像
FROM nginx:alpine

# 复制构建产物
COPY --from=builder /app/dist /usr/share/nginx/html

# 复制nginx配置
COPY nginx.conf /etc/nginx/nginx.conf

# 暴露端口
EXPOSE 80

# 启动命令
CMD ["nginx", "-g", "daemon off;"]
```

#### 后端Dockerfile
```dockerfile
# backend/Dockerfile
FROM node:18-alpine

# 设置工作目录
WORKDIR /app

# 创建非root用户
RUN addgroup -g 1001 -S nodejs
RUN adduser -S nodejs -u 1001

# 复制package文件
COPY package*.json ./

# 安装依赖
RUN npm ci --only=production && npm cache clean --force

# 复制源代码
COPY . .

# 更改文件所有者
RUN chown -R nodejs:nodejs /app
USER nodejs

# 暴露端口
EXPOSE 3000

# 健康检查
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
  CMD curl -f http://localhost:3000/health || exit 1

# 启动命令
CMD ["npm", "start"]
```

#### Docker Compose配置
```yaml
# docker-compose.yml
version: '3.8'

services:
  # 前端服务
  frontend:
    build:
      context: ./frontend
      dockerfile: Dockerfile
    container_name: jiebanke-frontend
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro
      - ./nginx/ssl:/etc/nginx/ssl:ro
    depends_on:
      - backend
    networks:
      - jiebanke-network
    restart: unless-stopped

  # 后端服务
  backend:
    build:
      context: ./backend
      dockerfile: Dockerfile
    container_name: jiebanke-backend
    ports:
      - "3000:3000"
    environment:
      - NODE_ENV=production
      - DB_HOST=mysql
      - DB_PORT=3306
      - DB_NAME=jiebanke
      - DB_USER=jiebanke_user
      - DB_PASSWORD=${DB_PASSWORD}
      - REDIS_HOST=redis
      - REDIS_PORT=6379
      - JWT_SECRET=${JWT_SECRET}
      - MINIO_ENDPOINT=minio
      - MINIO_PORT=9000
      - MINIO_ACCESS_KEY=${MINIO_ACCESS_KEY}
      - MINIO_SECRET_KEY=${MINIO_SECRET_KEY}
    volumes:
      - ./logs:/app/logs
      - ./uploads:/app/uploads
    depends_on:
      - mysql
      - redis
      - minio
    networks:
      - jiebanke-network
    restart: unless-stopped
    deploy:
      resources:
        limits:
          memory: 512M
          cpus: '0.5'
        reservations:
          memory: 256M
          cpus: '0.25'

  # MySQL数据库
  mysql:
    image: mysql:8.0
    container_name: jiebanke-mysql
    ports:
      - "3306:3306"
    environment:
      - MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD}
      - MYSQL_DATABASE=jiebanke
      - MYSQL_USER=jiebanke_user
      - MYSQL_PASSWORD=${DB_PASSWORD}
    volumes:
      - mysql_data:/var/lib/mysql
      - ./mysql/conf.d:/etc/mysql/conf.d:ro
      - ./mysql/init:/docker-entrypoint-initdb.d:ro
    networks:
      - jiebanke-network
    restart: unless-stopped
    command: --default-authentication-plugin=mysql_native_password

  # Redis缓存
  redis:
    image: redis:7-alpine
    container_name: jiebanke-redis
    ports:
      - "6379:6379"
    volumes:
      - redis_data:/data
      - ./redis/redis.conf:/usr/local/etc/redis/redis.conf:ro
    networks:
      - jiebanke-network
    restart: unless-stopped
    command: redis-server /usr/local/etc/redis/redis.conf

  # MinIO对象存储
  minio:
    image: minio/minio:latest
    container_name: jiebanke-minio
    ports:
      - "9000:9000"
      - "9001:9001"
    environment:
      - MINIO_ROOT_USER=${MINIO_ACCESS_KEY}
      - MINIO_ROOT_PASSWORD=${MINIO_SECRET_KEY}
    volumes:
      - minio_data:/data
    networks:
      - jiebanke-network
    restart: unless-stopped
    command: server /data --console-address ":9001"

  # Nginx负载均衡
  nginx:
    image: nginx:alpine
    container_name: jiebanke-nginx
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro
      - ./nginx/ssl:/etc/nginx/ssl:ro
      - ./nginx/logs:/var/log/nginx
    depends_on:
      - backend
    networks:
      - jiebanke-network
    restart: unless-stopped

  # Prometheus监控
  prometheus:
    image: prom/prometheus:latest
    container_name: jiebanke-prometheus
    ports:
      - "9090:9090"
    volumes:
      - ./monitoring/prometheus.yml:/etc/prometheus/prometheus.yml:ro
      - prometheus_data:/prometheus
    networks:
      - jiebanke-network
    restart: unless-stopped
    command:
      - '--config.file=/etc/prometheus/prometheus.yml'
      - '--storage.tsdb.path=/prometheus'
      - '--web.console.libraries=/etc/prometheus/console_libraries'
      - '--web.console.templates=/etc/prometheus/consoles'

  # Grafana可视化
  grafana:
    image: grafana/grafana:latest
    container_name: jiebanke-grafana
    ports:
      - "3001:3000"
    environment:
      - GF_SECURITY_ADMIN_PASSWORD=${GRAFANA_PASSWORD}
    volumes:
      - grafana_data:/var/lib/grafana
      - ./monitoring/grafana/dashboards:/etc/grafana/provisioning/dashboards:ro
      - ./monitoring/grafana/datasources:/etc/grafana/provisioning/datasources:ro
    depends_on:
      - prometheus
    networks:
      - jiebanke-network
    restart: unless-stopped

volumes:
  mysql_data:
  redis_data:
  minio_data:
  prometheus_data:
  grafana_data:

networks:
  jiebanke-network:
    driver: bridge
```

### 环境配置

#### 环境变量配置
```bash
# .env.production
# 数据库配置
DB_PASSWORD=your_secure_db_password
MYSQL_ROOT_PASSWORD=your_secure_root_password

# JWT配置
JWT_SECRET=your_jwt_secret_key_here

# MinIO配置
MINIO_ACCESS_KEY=your_minio_access_key
MINIO_SECRET_KEY=your_minio_secret_key

# Grafana配置
GRAFANA_PASSWORD=your_grafana_password

# 邮件配置
SMTP_HOST=smtp.example.com
SMTP_PORT=587
SMTP_USER=your_email@example.com
SMTP_PASSWORD=your_email_password

# 微信小程序配置
WECHAT_APP_ID=your_wechat_app_id
WECHAT_APP_SECRET=your_wechat_app_secret

# 阿里云配置
ALIYUN_ACCESS_KEY_ID=your_aliyun_access_key
ALIYUN_ACCESS_KEY_SECRET=your_aliyun_secret_key
ALIYUN_OSS_BUCKET=your_oss_bucket_name
ALIYUN_OSS_REGION=your_oss_region
```

## 🚀 部署流程

### 自动化部署脚本

#### 部署脚本
```bash
#!/bin/bash
# deploy.sh - 自动化部署脚本

set -e

# 配置变量
PROJECT_NAME="jiebanke"
DEPLOY_ENV=${1:-production}
BACKUP_DIR="/backup"
LOG_FILE="/var/log/deploy.log"

# 日志函数
log() {
    echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a $LOG_FILE
}

# 错误处理
error_exit() {
    log "ERROR: $1"
    exit 1
}

# 检查环境
check_environment() {
    log "检查部署环境..."
    
    # 检查Docker
    if ! command -v docker &> /dev/null; then
        error_exit "Docker未安装"
    fi
    
    # 检查Docker Compose
    if ! command -v docker-compose &> /dev/null; then
        error_exit "Docker Compose未安装"
    fi
    
    # 检查环境变量文件
    if [ ! -f ".env.${DEPLOY_ENV}" ]; then
        error_exit "环境变量文件 .env.${DEPLOY_ENV} 不存在"
    fi
    
    log "环境检查完成"
}

# 备份数据
backup_data() {
    log "开始数据备份..."
    
    # 创建备份目录
    BACKUP_PATH="${BACKUP_DIR}/$(date +%Y%m%d_%H%M%S)"
    mkdir -p $BACKUP_PATH
    
    # 备份数据库
    docker exec jiebanke-mysql mysqldump -u root -p${MYSQL_ROOT_PASSWORD} jiebanke > "${BACKUP_PATH}/database.sql"
    
    # 备份Redis数据
    docker exec jiebanke-redis redis-cli BGSAVE
    docker cp jiebanke-redis:/data/dump.rdb "${BACKUP_PATH}/redis.rdb"
    
    # 备份上传文件
    if [ -d "./uploads" ]; then
        tar -czf "${BACKUP_PATH}/uploads.tar.gz" ./uploads
    fi
    
    log "数据备份完成: $BACKUP_PATH"
}

# 拉取最新代码
pull_code() {
    log "拉取最新代码..."
    
    # 检查Git状态
    if [ -d ".git" ]; then
        git fetch origin
        git reset --hard origin/main
        log "代码更新完成"
    else
        error_exit "不是Git仓库"
    fi
}

# 构建镜像
build_images() {
    log "构建Docker镜像..."
    
    # 构建前端镜像
    docker build -t ${PROJECT_NAME}-frontend:latest ./frontend
    
    # 构建后端镜像
    docker build -t ${PROJECT_NAME}-backend:latest ./backend
    
    log "镜像构建完成"
}

# 部署服务
deploy_services() {
    log "部署服务..."
    
    # 复制环境变量文件
    cp .env.${DEPLOY_ENV} .env
    
    # 停止旧服务
    docker-compose down
    
    # 启动新服务
    docker-compose up -d
    
    # 等待服务启动
    sleep 30
    
    log "服务部署完成"
}

# 健康检查
health_check() {
    log "执行健康检查..."
    
    # 检查后端服务
    if ! curl -f http://localhost:3000/health > /dev/null 2>&1; then
        error_exit "后端服务健康检查失败"
    fi
    
    # 检查前端服务
    if ! curl -f http://localhost > /dev/null 2>&1; then
        error_exit "前端服务健康检查失败"
    fi
    
    # 检查数据库连接
    if ! docker exec jiebanke-mysql mysqladmin ping -h localhost > /dev/null 2>&1; then
        error_exit "数据库连接检查失败"
    fi
    
    log "健康检查通过"
}

# 清理旧镜像
cleanup() {
    log "清理旧镜像..."
    
    # 删除未使用的镜像
    docker image prune -f
    
    # 删除未使用的容器
    docker container prune -f
    
    # 删除未使用的网络
    docker network prune -f
    
    log "清理完成"
}

# 发送通知
send_notification() {
    local status=$1
    local message="解班客项目部署${status}: ${DEPLOY_ENV}环境"
    
    log $message
    
    # 这里可以集成钉钉、企业微信等通知
    # curl -X POST "https://oapi.dingtalk.com/robot/send?access_token=YOUR_TOKEN" \
    #      -H 'Content-Type: application/json' \
    #      -d "{\"msgtype\": \"text\", \"text\": {\"content\": \"$message\"}}"
}

# 主函数
main() {
    log "开始部署 ${PROJECT_NAME} 到 ${DEPLOY_ENV} 环境"
    
    # 检查环境
    check_environment
    
    # 备份数据
    backup_data
    
    # 拉取代码
    pull_code
    
    # 构建镜像
    build_images
    
    # 部署服务
    deploy_services
    
    # 健康检查
    health_check
    
    # 清理资源
    cleanup
    
    # 发送成功通知
    send_notification "成功"
    
    log "部署完成"
}

# 错误处理
trap 'send_notification "失败"; exit 1' ERR

# 执行主函数
main "$@"
```

#### 回滚脚本
```bash
#!/bin/bash
# rollback.sh - 回滚脚本

set -e

PROJECT_NAME="jiebanke"
BACKUP_DIR="/backup"
LOG_FILE="/var/log/rollback.log"

# 日志函数
log() {
    echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a $LOG_FILE
}

# 列出可用备份
list_backups() {
    log "可用备份列表:"
    ls -la $BACKUP_DIR | grep "^d" | awk '{print $9}' | grep -E "^[0-9]{8}_[0-9]{6}$" | sort -r
}

# 回滚到指定备份
rollback_to_backup() {
    local backup_name=$1
    local backup_path="${BACKUP_DIR}/${backup_name}"
    
    if [ ! -d "$backup_path" ]; then
        log "ERROR: 备份目录不存在: $backup_path"
        exit 1
    fi
    
    log "开始回滚到备份: $backup_name"
    
    # 停止当前服务
    docker-compose down
    
    # 恢复数据库
    if [ -f "${backup_path}/database.sql" ]; then
        log "恢复数据库..."
        docker-compose up -d mysql
        sleep 10
        docker exec -i jiebanke-mysql mysql -u root -p${MYSQL_ROOT_PASSWORD} jiebanke < "${backup_path}/database.sql"
    fi
    
    # 恢复Redis数据
    if [ -f "${backup_path}/redis.rdb" ]; then
        log "恢复Redis数据..."
        docker cp "${backup_path}/redis.rdb" jiebanke-redis:/data/dump.rdb
        docker-compose restart redis
    fi
    
    # 恢复上传文件
    if [ -f "${backup_path}/uploads.tar.gz" ]; then
        log "恢复上传文件..."
        rm -rf ./uploads
        tar -xzf "${backup_path}/uploads.tar.gz"
    fi
    
    # 启动所有服务
    docker-compose up -d
    
    log "回滚完成"
}

# 主函数
main() {
    if [ $# -eq 0 ]; then
        list_backups
        echo "使用方法: $0 <backup_name>"
        exit 1
    fi
    
    rollback_to_backup $1
}

main "$@"
```

## 📊 监控配置

### Prometheus配置
```yaml
# monitoring/prometheus.yml
global:
  scrape_interval: 15s
  evaluation_interval: 15s

rule_files:
  - "rules/*.yml"

alerting:
  alertmanagers:
    - static_configs:
        - targets:
          - alertmanager:9093

scrape_configs:
  # Prometheus自身监控
  - job_name: 'prometheus'
    static_configs:
      - targets: ['localhost:9090']

  # Node.js应用监控
  - job_name: 'jiebanke-backend'
    static_configs:
      - targets: ['backend:3000']
    metrics_path: '/metrics'
    scrape_interval: 10s

  # MySQL监控
  - job_name: 'mysql'
    static_configs:
      - targets: ['mysql-exporter:9104']

  # Redis监控
  - job_name: 'redis'
    static_configs:
      - targets: ['redis-exporter:9121']

  # Nginx监控
  - job_name: 'nginx'
    static_configs:
      - targets: ['nginx-exporter:9113']

  # 系统监控
  - job_name: 'node'
    static_configs:
      - targets: ['node-exporter:9100']
```

### 告警规则
```yaml
# monitoring/rules/alerts.yml
groups:
  - name: jiebanke-alerts
    rules:
      # 服务可用性告警
      - alert: ServiceDown
        expr: up == 0
        for: 1m
        labels:
          severity: critical
        annotations:
          summary: "服务 {{ $labels.job }} 不可用"
          description: "服务 {{ $labels.job }} 已经停止响应超过1分钟"

      # 高响应时间告警
      - alert: HighResponseTime
        expr: http_request_duration_seconds{quantile="0.95"} > 1
        for: 2m
        labels:
          severity: warning
        annotations:
          summary: "响应时间过高"
          description: "95%的请求响应时间超过1秒，当前值: {{ $value }}s"

      # 高错误率告警
      - alert: HighErrorRate
        expr: rate(http_requests_total{status=~"5.."}[5m]) / rate(http_requests_total[5m]) > 0.05
        for: 2m
        labels:
          severity: critical
        annotations:
          summary: "错误率过高"
          description: "5分钟内错误率超过5%，当前值: {{ $value | humanizePercentage }}"

      # 内存使用率告警
      - alert: HighMemoryUsage
        expr: (node_memory_MemTotal_bytes - node_memory_MemAvailable_bytes) / node_memory_MemTotal_bytes > 0.8
        for: 5m
        labels:
          severity: warning
        annotations:
          summary: "内存使用率过高"
          description: "内存使用率超过80%，当前值: {{ $value | humanizePercentage }}"

      # CPU使用率告警
      - alert: HighCPUUsage
        expr: 100 - (avg by(instance) (irate(node_cpu_seconds_total{mode="idle"}[5m])) * 100) > 80
        for: 5m
        labels:
          severity: warning
        annotations:
          summary: "CPU使用率过高"
          description: "CPU使用率超过80%，当前值: {{ $value }}%"

      # 磁盘空间告警
      - alert: DiskSpaceLow
        expr: (node_filesystem_avail_bytes / node_filesystem_size_bytes) < 0.1
        for: 1m
        labels:
          severity: critical
        annotations:
          summary: "磁盘空间不足"
          description: "磁盘 {{ $labels.mountpoint }} 可用空间少于10%"

      # 数据库连接数告警
      - alert: MySQLHighConnections
        expr: mysql_global_status_threads_connected / mysql_global_variables_max_connections > 0.8
        for: 2m
        labels:
          severity: warning
        annotations:
          summary: "MySQL连接数过高"
          description: "MySQL连接数超过最大连接数的80%"

      # Redis内存使用告警
      - alert: RedisHighMemoryUsage
        expr: redis_memory_used_bytes / redis_memory_max_bytes > 0.8
        for: 2m
        labels:
          severity: warning
        annotations:
          summary: "Redis内存使用率过高"
          description: "Redis内存使用率超过80%"
```

## 🔧 运维管理

### 日志管理

#### 日志收集配置
```yaml
# logging/filebeat.yml
filebeat.inputs:
  # 应用日志
  - type: log
    enabled: true
    paths:
      - /app/logs/*.log
    fields:
      service: jiebanke-backend
      environment: production
    multiline.pattern: '^\d{4}-\d{2}-\d{2}'
    multiline.negate: true
    multiline.match: after

  # Nginx访问日志
  - type: log
    enabled: true
    paths:
      - /var/log/nginx/access.log
    fields:
      service: nginx
      log_type: access

  # Nginx错误日志
  - type: log
    enabled: true
    paths:
      - /var/log/nginx/error.log
    fields:
      service: nginx
      log_type: error

output.elasticsearch:
  hosts: ["elasticsearch:9200"]
  index: "jiebanke-logs-%{+yyyy.MM.dd}"

processors:
  - add_host_metadata:
      when.not.contains.tags: forwarded
  - add_docker_metadata: ~
  - add_kubernetes_metadata: ~
```

#### 日志轮转配置
```bash
# /etc/logrotate.d/jiebanke
/app/logs/*.log {
    daily
    missingok
    rotate 30
    compress
    delaycompress
    notifempty
    create 0644 nodejs nodejs
    postrotate
        docker kill -s USR1 jiebanke-backend
    endscript
}

/var/log/nginx/*.log {
    daily
    missingok
    rotate 52
    compress
    delaycompress
    notifempty
    create 0644 nginx nginx
    postrotate
        docker kill -s USR1 jiebanke-nginx
    endscript
}
```

### 备份策略

#### 自动备份脚本
```bash
#!/bin/bash
# backup.sh - 自动备份脚本

BACKUP_DIR="/backup"
RETENTION_DAYS=30
LOG_FILE="/var/log/backup.log"

# 日志函数
log() {
    echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a $LOG_FILE
}

# 创建备份
create_backup() {
    local backup_name=$(date +%Y%m%d_%H%M%S)
    local backup_path="${BACKUP_DIR}/${backup_name}"
    
    mkdir -p $backup_path
    
    log "开始创建备份: $backup_name"
    
    # 备份数据库
    log "备份MySQL数据库..."
    docker exec jiebanke-mysql mysqldump \
        -u root -p${MYSQL_ROOT_PASSWORD} \
        --single-transaction \
        --routines \
        --triggers \
        jiebanke > "${backup_path}/database.sql"
    
    # 备份Redis
    log "备份Redis数据..."
    docker exec jiebanke-redis redis-cli BGSAVE
    docker cp jiebanke-redis:/data/dump.rdb "${backup_path}/redis.rdb"
    
    # 备份上传文件
    log "备份上传文件..."
    if [ -d "./uploads" ]; then
        tar -czf "${backup_path}/uploads.tar.gz" ./uploads
    fi
    
    # 备份配置文件
    log "备份配置文件..."
    tar -czf "${backup_path}/config.tar.gz" \
        docker-compose.yml \
        .env.production \
        nginx/ \
        monitoring/
    
    # 压缩备份
    log "压缩备份文件..."
    cd $BACKUP_DIR
    tar -czf "${backup_name}.tar.gz" $backup_name
    rm -rf $backup_name
    
    log "备份完成: ${backup_name}.tar.gz"
}

# 清理旧备份
cleanup_old_backups() {
    log "清理${RETENTION_DAYS}天前的备份..."
    
    find $BACKUP_DIR -name "*.tar.gz" -mtime +$RETENTION_DAYS -delete
    
    log "旧备份清理完成"
}

# 上传到云存储
upload_to_cloud() {
    local backup_file=$1
    
    # 这里可以集成阿里云OSS、AWS S3等
    log "上传备份到云存储: $backup_file"
    
    # 示例：上传到阿里云OSS
    # ossutil cp $backup_file oss://your-bucket/backups/
}

# 主函数
main() {
    create_backup
    cleanup_old_backups
    
    # 可选：上传最新备份到云存储
    # latest_backup=$(ls -t ${BACKUP_DIR}/*.tar.gz | head -1)
    # upload_to_cloud $latest_backup
}

main "$@"
```

### 性能调优

#### MySQL优化配置
```ini
# mysql/conf.d/my.cnf
[mysqld]
# 基本设置
default-storage-engine = InnoDB
character-set-server = utf8mb4
collation-server = utf8mb4_unicode_ci

# 连接设置
max_connections = 200
max_connect_errors = 1000
wait_timeout = 28800
interactive_timeout = 28800

# 缓冲区设置
innodb_buffer_pool_size = 1G
innodb_buffer_pool_instances = 4
innodb_log_file_size = 256M
innodb_log_buffer_size = 16M

# 查询缓存
query_cache_type = 1
query_cache_size = 128M
query_cache_limit = 2M

# 临时表设置
tmp_table_size = 64M
max_heap_table_size = 64M

# 慢查询日志
slow_query_log = 1
slow_query_log_file = /var/log/mysql/slow.log
long_query_time = 2

# 二进制日志
log-bin = mysql-bin
binlog_format = ROW
expire_logs_days = 7

# InnoDB设置
innodb_file_per_table = 1
innodb_flush_log_at_trx_commit = 2
innodb_flush_method = O_DIRECT
innodb_io_capacity = 200
```

#### Redis优化配置
```conf
# redis/redis.conf
# 内存设置
maxmemory 512mb
maxmemory-policy allkeys-lru

# 持久化设置
save 900 1
save 300 10
save 60 10000

# AOF设置
appendonly yes
appendfsync everysec
no-appendfsync-on-rewrite no
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb

# 网络设置
tcp-keepalive 300
timeout 0

# 安全设置
requirepass your_redis_password

# 日志设置
loglevel notice
logfile /var/log/redis/redis-server.log

# 客户端连接
maxclients 10000
```

## 🎯 总结

本部署和运维文档提供了解班客项目的完整部署和运维方案，包括：

### 核心特性
1. **容器化部署**：使用Docker和Docker Compose实现标准化部署
2. **自动化运维**：提供自动化部署、备份、回滚脚本
3. **监控告警**：基于Prometheus和Grafana的完整监控体系
4. **日志管理**：集中化日志收集和分析
5. **高可用架构**：负载均衡、数据备份、故障恢复

### 运维流程
1. **部署流程**：代码拉取 → 镜像构建 → 服务部署 → 健康检查
2. **监控体系**：指标收集 → 可视化展示 → 告警通知
3. **备份策略**：定期备份 → 云端存储 → 快速恢复
4. **性能优化**：数据库调优 → 缓存优化 → 系统监控

通过标准化的部署和运维流程，确保解班客项目能够稳定、高效地为用户提供服务。