# 结伴客项目部署文档 ## 1. 部署概述 ### 1.1 部署架构 ```mermaid graph TB A[用户] --> B[CDN/负载均衡] B --> C[Nginx反向代理] C --> D[小程序静态资源] C --> E[管理后台静态资源] C --> F[后端API服务] F --> G[Redis缓存] F --> H[MySQL主库] H --> I[MySQL从库] F --> J[文件存储OSS] F --> K[消息队列] subgraph "服务器集群" L[Web服务器1] M[Web服务器2] N[API服务器1] O[API服务器2] end C --> L C --> M F --> N F --> O ``` ### 1.2 环境规划 | 环境 | 用途 | 服务器配置 | 域名 | |------|------|------------|------| | 开发环境 | 开发测试 | 2C4G | dev.jiebanke.com | | 测试环境 | 功能测试 | 4C8G | test.jiebanke.com | | 预发布环境 | 集成测试 | 8C16G | pre.jiebanke.com | | 生产环境 | 线上服务 | 16C32G | www.jiebanke.com | ## 2. 服务器环境准备 ### 2.1 系统要求 ```bash # CentOS 7/8 或 Ubuntu 18.04+ # 最低配置:4C8G,推荐:8C16G # 磁盘空间:100GB+ # 网络:带宽10Mbps+ # 系统更新 sudo yum update -y # CentOS sudo apt update && sudo apt upgrade -y # Ubuntu ``` ### 2.2 基础软件安装 ```bash #!/bin/bash # install-base.sh - 基础环境安装脚本 # 安装Docker curl -fsSL https://get.docker.com | bash sudo systemctl start docker sudo systemctl enable docker sudo usermod -aG docker $USER # 安装Docker Compose sudo curl -L "https://github.com/docker/compose/releases/download/v2.20.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose sudo chmod +x /usr/local/bin/docker-compose # 安装Node.js curl -fsSL https://rpm.nodesource.com/setup_18.x | sudo bash - sudo yum install -y nodejs # 安装PM2 sudo npm install -g pm2 # 安装Nginx sudo yum install -y nginx sudo systemctl start nginx sudo systemctl enable nginx echo "基础环境安装完成" ``` ### 2.3 目录结构规划 ```bash # 创建项目目录结构 sudo mkdir -p /opt/jiebanke/{ backend, admin-system, mini-program, website, nginx, logs, data, scripts, ssl } # 设置权限 sudo chown -R $USER:$USER /opt/jiebanke chmod -R 755 /opt/jiebanke ``` ## 3. 数据库部署 ### 3.1 MySQL主从部署 ```yaml # docker-compose-mysql.yml version: '3.8' services: mysql-master: image: mysql:8.0 container_name: mysql-master environment: MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD} MYSQL_DATABASE: jiebanke MYSQL_USER: jiebanke MYSQL_PASSWORD: ${MYSQL_PASSWORD} volumes: - ./data/mysql-master:/var/lib/mysql - ./config/mysql-master.cnf:/etc/mysql/conf.d/mysql.cnf ports: - "3306:3306" command: --server-id=1 --log-bin=mysql-bin --binlog-format=ROW networks: - jiebanke-network mysql-slave: image: mysql:8.0 container_name: mysql-slave environment: MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD} MYSQL_DATABASE: jiebanke MYSQL_USER: jiebanke MYSQL_PASSWORD: ${MYSQL_PASSWORD} volumes: - ./data/mysql-slave:/var/lib/mysql - ./config/mysql-slave.cnf:/etc/mysql/conf.d/mysql.cnf ports: - "3307:3306" command: --server-id=2 --relay-log=relay-bin --read-only=1 depends_on: - mysql-master networks: - jiebanke-network networks: jiebanke-network: driver: bridge ``` ### 3.2 Redis集群部署 ```yaml # docker-compose-redis.yml version: '3.8' services: redis-master: image: redis:7-alpine container_name: redis-master ports: - "6379:6379" volumes: - ./data/redis-master:/data - ./config/redis-master.conf:/usr/local/etc/redis/redis.conf command: redis-server /usr/local/etc/redis/redis.conf networks: - jiebanke-network redis-slave: image: redis:7-alpine container_name: redis-slave ports: - "6380:6379" volumes: - ./data/redis-slave:/data - ./config/redis-slave.conf:/usr/local/etc/redis/redis.conf command: redis-server /usr/local/etc/redis/redis.conf --slaveof redis-master 6379 depends_on: - redis-master networks: - jiebanke-network ``` ## 4. 后端服务部署 ### 4.1 后端API服务 ```dockerfile # backend/Dockerfile FROM node:18-alpine WORKDIR /app # 复制package文件 COPY package*.json ./ RUN npm ci --only=production # 复制源代码 COPY . . # 构建应用 RUN npm run build # 暴露端口 EXPOSE 3000 # 启动命令 CMD ["npm", "start"] ``` ### 4.2 PM2配置 ```javascript // ecosystem.config.js module.exports = { apps: [{ name: 'jiebanke-api', script: './dist/app.js', instances: 'max', exec_mode: 'cluster', env: { NODE_ENV: 'production', PORT: 3000 }, env_production: { NODE_ENV: 'production', PORT: 3000, DB_HOST: 'localhost', DB_PORT: 3306, DB_NAME: 'jiebanke', REDIS_HOST: 'localhost', REDIS_PORT: 6379 }, log_file: '/opt/jiebanke/logs/api.log', error_file: '/opt/jiebanke/logs/api-error.log', out_file: '/opt/jiebanke/logs/api-out.log', log_date_format: 'YYYY-MM-DD HH:mm:ss', max_memory_restart: '1G', node_args: '--max_old_space_size=1024' }] }; ``` ### 4.3 部署脚本 ```bash #!/bin/bash # deploy-backend.sh - 后端部署脚本 set -e PROJECT_DIR="/opt/jiebanke" BACKEND_DIR="$PROJECT_DIR/backend" BACKUP_DIR="$PROJECT_DIR/backup/$(date +%Y%m%d_%H%M%S)" echo "开始部署后端服务..." # 创建备份 if [ -d "$BACKEND_DIR" ]; then echo "创建备份..." mkdir -p "$BACKUP_DIR" cp -r "$BACKEND_DIR" "$BACKUP_DIR/" fi # 拉取最新代码 cd "$PROJECT_DIR" git pull origin main # 安装依赖 cd "$BACKEND_DIR" npm ci --only=production # 构建项目 npm run build # 数据库迁移 npm run migrate # 重启服务 pm2 reload ecosystem.config.js --env production # 健康检查 sleep 10 if curl -f http://localhost:3000/health; then echo "后端服务部署成功" else echo "后端服务部署失败,回滚..." pm2 stop jiebanke-api rm -rf "$BACKEND_DIR" cp -r "$BACKUP_DIR/backend" "$PROJECT_DIR/" cd "$BACKEND_DIR" pm2 start ecosystem.config.js --env production exit 1 fi ``` ## 5. 前端部署 ### 5.1 管理后台部署 ```bash #!/bin/bash # deploy-admin.sh - 管理后台部署脚本 set -e PROJECT_DIR="/opt/jiebanke" ADMIN_DIR="$PROJECT_DIR/admin-system" NGINX_DIR="/var/www/admin" echo "开始部署管理后台..." # 构建项目 cd "$ADMIN_DIR" npm ci npm run build # 部署到Nginx目录 sudo rm -rf "$NGINX_DIR" sudo mkdir -p "$NGINX_DIR" sudo cp -r dist/* "$NGINX_DIR/" sudo chown -R nginx:nginx "$NGINX_DIR" # 重载Nginx配置 sudo nginx -t && sudo nginx -s reload echo "管理后台部署完成" ``` ### 5.2 小程序部署 ```bash #!/bin/bash # deploy-miniprogram.sh - 小程序部署脚本 set -e PROJECT_DIR="/opt/jiebanke" MINI_DIR="$PROJECT_DIR/mini-program" echo "开始构建小程序..." cd "$MINI_DIR" npm ci npm run build echo "小程序构建完成,请使用微信开发者工具上传" echo "构建产物位置: $MINI_DIR/dist" ``` ## 6. Nginx配置 ### 6.1 主配置文件 ```nginx # /etc/nginx/nginx.conf user nginx; worker_processes auto; error_log /var/log/nginx/error.log; pid /run/nginx.pid; events { worker_connections 1024; use epoll; multi_accept on; } http { include /etc/nginx/mime.types; default_type application/octet-stream; # 日志格式 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; client_max_body_size 50M; # Gzip压缩 gzip on; gzip_vary on; gzip_min_length 1024; gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript; # 包含站点配置 include /etc/nginx/conf.d/*.conf; } ``` ### 6.2 站点配置 ```nginx # /etc/nginx/conf.d/jiebanke.conf # API服务负载均衡 upstream api_backend { server 127.0.0.1:3000 weight=1 max_fails=3 fail_timeout=30s; server 127.0.0.1:3001 weight=1 max_fails=3 fail_timeout=30s; keepalive 32; } # 管理后台 server { listen 80; server_name admin.jiebanke.com; return 301 https://$server_name$request_uri; } server { listen 443 ssl http2; server_name admin.jiebanke.com; # SSL配置 ssl_certificate /opt/jiebanke/ssl/admin.crt; ssl_certificate_key /opt/jiebanke/ssl/admin.key; ssl_protocols TLSv1.2 TLSv1.3; ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384; ssl_prefer_server_ciphers off; root /var/www/admin; index index.html; # 静态资源缓存 location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ { expires 1y; add_header Cache-Control "public, immutable"; } # SPA路由支持 location / { try_files $uri $uri/ /index.html; } # API代理 location /api/ { proxy_pass http://api_backend; 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; } } # API服务 server { listen 80; server_name api.jiebanke.com; return 301 https://$server_name$request_uri; } server { listen 443 ssl http2; server_name api.jiebanke.com; # SSL配置 ssl_certificate /opt/jiebanke/ssl/api.crt; ssl_certificate_key /opt/jiebanke/ssl/api.key; ssl_protocols TLSv1.2 TLSv1.3; ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384; ssl_prefer_server_ciphers off; # API代理 location / { proxy_pass http://api_backend; 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; # CORS配置 add_header Access-Control-Allow-Origin *; add_header Access-Control-Allow-Methods 'GET, POST, PUT, DELETE, OPTIONS'; add_header Access-Control-Allow-Headers 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization'; if ($request_method = 'OPTIONS') { return 204; } } } ``` ## 7. SSL证书配置 ### 7.1 Let's Encrypt证书 ```bash #!/bin/bash # ssl-setup.sh - SSL证书配置脚本 # 安装certbot sudo yum install -y certbot python3-certbot-nginx # 申请证书 sudo certbot --nginx -d admin.jiebanke.com -d api.jiebanke.com # 设置自动续期 echo "0 12 * * * /usr/bin/certbot renew --quiet" | sudo crontab - ``` ### 7.2 证书更新脚本 ```bash #!/bin/bash # renew-ssl.sh - SSL证书更新脚本 # 更新证书 certbot renew --quiet # 重载Nginx if [ $? -eq 0 ]; then nginx -s reload echo "SSL证书更新成功" else echo "SSL证书更新失败" exit 1 fi ``` ## 8. 监控和日志 ### 8.1 系统监控 ```yaml # docker-compose-monitoring.yml version: '3.8' services: prometheus: image: prom/prometheus:latest container_name: prometheus ports: - "9090:9090" volumes: - ./config/prometheus.yml:/etc/prometheus/prometheus.yml - prometheus_data:/prometheus 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: image: grafana/grafana:latest container_name: grafana ports: - "3001:3000" volumes: - grafana_data:/var/lib/grafana environment: - GF_SECURITY_ADMIN_PASSWORD=admin123 node-exporter: image: prom/node-exporter:latest container_name: node-exporter ports: - "9100:9100" volumes: - /proc:/host/proc:ro - /sys:/host/sys:ro - /:/rootfs:ro command: - '--path.procfs=/host/proc' - '--path.sysfs=/host/sys' - '--collector.filesystem.ignored-mount-points=^/(sys|proc|dev|host|etc)($$|/)' volumes: prometheus_data: grafana_data: ``` ### 8.2 日志管理 ```yaml # docker-compose-logging.yml version: '3.8' services: elasticsearch: image: docker.elastic.co/elasticsearch/elasticsearch:8.8.0 container_name: elasticsearch environment: - discovery.type=single-node - "ES_JAVA_OPTS=-Xms512m -Xmx512m" - xpack.security.enabled=false ports: - "9200:9200" volumes: - elasticsearch_data:/usr/share/elasticsearch/data logstash: image: docker.elastic.co/logstash/logstash:8.8.0 container_name: logstash ports: - "5044:5044" volumes: - ./config/logstash.conf:/usr/share/logstash/pipeline/logstash.conf depends_on: - elasticsearch kibana: image: docker.elastic.co/kibana/kibana:8.8.0 container_name: kibana ports: - "5601:5601" environment: - ELASTICSEARCH_HOSTS=http://elasticsearch:9200 depends_on: - elasticsearch volumes: elasticsearch_data: ``` ## 9. 备份和恢复 ### 9.1 数据库备份 ```bash #!/bin/bash # backup-database.sh - 数据库备份脚本 BACKUP_DIR="/opt/jiebanke/backup/database" DATE=$(date +%Y%m%d_%H%M%S) DB_NAME="jiebanke" DB_USER="root" DB_PASSWORD="your_password" # 创建备份目录 mkdir -p "$BACKUP_DIR" # 备份数据库 mysqldump -u"$DB_USER" -p"$DB_PASSWORD" "$DB_NAME" > "$BACKUP_DIR/jiebanke_$DATE.sql" # 压缩备份文件 gzip "$BACKUP_DIR/jiebanke_$DATE.sql" # 删除7天前的备份 find "$BACKUP_DIR" -name "*.sql.gz" -mtime +7 -delete echo "数据库备份完成: jiebanke_$DATE.sql.gz" ``` ### 9.2 文件备份 ```bash #!/bin/bash # backup-files.sh - 文件备份脚本 BACKUP_DIR="/opt/jiebanke/backup/files" DATE=$(date +%Y%m%d_%H%M%S) SOURCE_DIRS=("/opt/jiebanke/backend" "/var/www/admin" "/opt/jiebanke/data") # 创建备份目录 mkdir -p "$BACKUP_DIR" # 备份文件 for dir in "${SOURCE_DIRS[@]}"; do if [ -d "$dir" ]; then tar -czf "$BACKUP_DIR/$(basename $dir)_$DATE.tar.gz" -C "$(dirname $dir)" "$(basename $dir)" fi done # 删除30天前的备份 find "$BACKUP_DIR" -name "*.tar.gz" -mtime +30 -delete echo "文件备份完成" ``` ## 10. 部署检查清单 ### 10.1 部署前检查 - [ ] 服务器资源充足(CPU、内存、磁盘) - [ ] 网络连通性正常 - [ ] 域名DNS解析配置 - [ ] SSL证书准备就绪 - [ ] 数据库连接测试 - [ ] 缓存服务正常 - [ ] 文件存储服务配置 ### 10.2 部署后验证 - [ ] 服务启动状态检查 - [ ] 接口功能测试 - [ ] 前端页面访问测试 - [ ] 数据库连接测试 - [ ] 缓存功能测试 - [ ] 日志输出正常 - [ ] 监控指标正常 - [ ] 备份任务配置 ### 10.3 性能验证 - [ ] 接口响应时间 < 500ms - [ ] 页面加载时间 < 2s - [ ] 并发处理能力测试 - [ ] 内存使用率 < 80% - [ ] CPU使用率 < 70% - [ ] 磁盘IO正常 ## 11. 故障排查 ### 11.1 常见问题 | 问题 | 可能原因 | 解决方案 | |------|----------|----------| | 服务无法启动 | 端口占用、配置错误 | 检查端口、配置文件 | | 数据库连接失败 | 网络、权限问题 | 检查网络、用户权限 | | 接口响应慢 | 数据库查询、网络延迟 | 优化查询、检查网络 | | 内存不足 | 内存泄漏、配置不当 | 检查内存使用、调整配置 | | SSL证书错误 | 证书过期、配置错误 | 更新证书、检查配置 | ### 11.2 日志查看命令 ```bash # 查看应用日志 pm2 logs jiebanke-api # 查看Nginx日志 tail -f /var/log/nginx/error.log tail -f /var/log/nginx/access.log # 查看系统日志 journalctl -u nginx -f journalctl -u docker -f # 查看容器日志 docker logs -f mysql-master docker logs -f redis-master ``` ## 12. 总结 本部署文档涵盖了结伴客项目的完整部署流程,包括: - **基础环境**:服务器配置、软件安装 - **数据库部署**:MySQL主从、Redis集群 - **应用部署**:后端API、前端应用 - **负载均衡**:Nginx配置、SSL证书 - **监控日志**:系统监控、日志管理 - **备份恢复**:数据备份、故障恢复 通过遵循本文档的部署流程,可以确保系统的稳定性、可靠性和可维护性。