Files
jiebanke/docs/部署文档.md

763 lines
16 KiB
Markdown
Raw Normal View History

# 结伴客项目部署文档
## 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证书
- **监控日志**:系统监控、日志管理
- **备份恢复**:数据备份、故障恢复
通过遵循本文档的部署流程,可以确保系统的稳定性、可靠性和可维护性。