- 基于 NestJS + TypeScript + MySQL + Redis 架构 - 完整的模块化设计(认证、用户、小组、游戏、预约等) - JWT 认证和 RBAC 权限控制系统 - Docker 容器化部署支持 - 添加 CLAUDE.md 项目开发指南 - 配置 .gitignore 忽略文件 Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
17 KiB
17 KiB
GameGroup 后端部署指导文档
目录
环境准备
系统要求
- Node.js: 18.x 或更高版本
- MySQL: 8.0 或更高版本
- 内存: 最低 2GB RAM,推荐 4GB+
- 存储: 最低 10GB 可用空间
必需软件
# 检查 Node.js 版本
node --version # 应该 >= 18.0.0
# 检查 npm 版本
npm --version
# 检查 MySQL 版本
mysql --version # 应该 >= 8.0
本地开发部署
1. 克隆项目并安装依赖
# 进入项目目录
cd d:\vscProg\backend
# 安装依赖
npm install
2. 配置环境变量
复制环境变量示例文件:
cp .env.example .env.development
编辑 .env.development 文件:
# 应用配置
NODE_ENV=development
PORT=3000
# 数据库配置
DB_TYPE=mysql
DB_HOST=localhost
DB_PORT=3306
DB_USERNAME=root
DB_PASSWORD=你的数据库密码
DB_DATABASE=gamegroup
DB_SYNCHRONIZE=true
DB_LOGGING=true
# JWT配置
JWT_SECRET=dev-secret-key-change-in-production
JWT_EXPIRES_IN=7d
# CORS配置
CORS_ORIGIN=http://localhost:8080
# 日志配置
LOG_LEVEL=debug
# 缓存配置
CACHE_TTL=300
CACHE_MAX=100
# 性能配置
ENABLE_COMPRESSION=true
QUERY_LIMIT=100
QUERY_TIMEOUT=30000
3. 创建数据库
# 登录 MySQL
mysql -u root -p
# 创建数据库
CREATE DATABASE gamegroup CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
# 创建用户(可选)
CREATE USER 'gamegroup'@'localhost' IDENTIFIED BY 'your_password';
GRANT ALL PRIVILEGES ON gamegroup.* TO 'gamegroup'@'localhost';
FLUSH PRIVILEGES;
EXIT;
4. 启动开发服务器
# 启动开发模式(支持热重载)
npm run start:dev
# 或者普通启动
npm run start
访问 http://localhost:3000 查看应用是否正常运行。 访问 http://localhost:3000/docs 查看 Swagger API 文档。
5. 运行测试
# 运行所有测试
npm test
# 运行测试并生成覆盖率报告
npm run test:cov
# 监听模式运行测试
npm run test:watch
生产环境部署
方式一:Docker 部署(推荐)
1. 准备配置文件
创建 .env.production 文件:
NODE_ENV=production
PORT=3000
# 数据库配置(使用强密码!)
DB_HOST=mysql
DB_PORT=3306
DB_USERNAME=gamegroup
DB_PASSWORD=生产环境强密码
DB_DATABASE=gamegroup
DB_SYNCHRONIZE=false
DB_LOGGING=false
DB_ROOT_PASSWORD=MySQL_Root强密码
# JWT配置(必须更换!)
JWT_SECRET=生产环境超长随机密钥_至少32位
JWT_EXPIRES_IN=7d
# CORS配置(限制为实际前端域名)
CORS_ORIGIN=https://your-frontend-domain.com
# 日志配置
LOG_LEVEL=info
# 缓存配置
CACHE_TTL=600
CACHE_MAX=1000
# 性能配置
ENABLE_COMPRESSION=true
QUERY_LIMIT=100
QUERY_TIMEOUT=30000
2. 构建和启动
# 构建生产镜像
docker-compose -f docker-compose.prod.yml build
# 启动服务(后台运行)
docker-compose -f docker-compose.prod.yml up -d
# 查看运行状态
docker-compose -f docker-compose.prod.yml ps
# 查看日志
docker-compose -f docker-compose.prod.yml logs -f backend
3. 健康检查
# 检查应用健康状态
curl http://localhost:3000/health
# 检查容器状态
docker ps
# 查看容器资源使用
docker stats
4. 停止服务
# 停止服务
docker-compose -f docker-compose.prod.yml down
# 停止服务并删除数据卷(谨慎使用!)
docker-compose -f docker-compose.prod.yml down -v
方式二:PM2 部署
1. 安装 PM2
npm install -g pm2
2. 构建应用
# 安装生产依赖
npm ci --only=production
# 构建项目
npm run build:prod
3. 启动应用
# 使用 PM2 启动
pm2 start ecosystem.config.js --env production
# 查看运行状态
pm2 status
# 查看日志
pm2 logs gamegroup-backend
# 查看实时监控
pm2 monit
4. 设置开机自启
# 保存当前 PM2 进程列表
pm2 save
# 设置开机自启
pm2 startup
# 根据提示执行相应命令(会因系统而异)
5. 常用 PM2 命令
# 重启应用
pm2 restart gamegroup-backend
# 停止应用
pm2 stop gamegroup-backend
# 删除应用
pm2 delete gamegroup-backend
# 重载应用(零停机重启)
pm2 reload gamegroup-backend
# 查看详细信息
pm2 show gamegroup-backend
# 清空日志
pm2 flush
方式三:直接使用 Node.js
1. 构建应用
npm run build:prod
2. 启动应用
# 设置环境变量并启动
export NODE_ENV=production
node dist/main.js
# 或使用 npm 脚本
npm run start:prod
⚠️ 不推荐直接使用 Node.js,因为没有进程管理和自动重启功能。
数据库配置
创建生产数据库
-- 创建数据库
CREATE DATABASE gamegroup
CHARACTER SET utf8mb4
COLLATE utf8mb4_unicode_ci;
-- 创建专用用户
CREATE USER 'gamegroup'@'%' IDENTIFIED BY '强密码';
-- 授予权限
GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, INDEX, ALTER
ON gamegroup.*
TO 'gamegroup'@'%';
FLUSH PRIVILEGES;
性能优化索引
USE gamegroup;
-- 用户表索引
CREATE INDEX idx_user_username ON user(username);
CREATE INDEX idx_user_email ON user(email);
CREATE INDEX idx_user_phone ON user(phone);
CREATE INDEX idx_user_is_member ON user(isMember);
-- 小组表索引
CREATE INDEX idx_group_owner ON `group`(ownerId);
CREATE INDEX idx_group_is_active ON `group`(isActive);
CREATE INDEX idx_group_is_public ON `group`(isPublic);
CREATE INDEX idx_group_created_at ON `group`(createdAt);
-- 小组成员表索引
CREATE INDEX idx_member_group_user ON group_member(groupId, userId);
CREATE INDEX idx_member_user ON group_member(userId);
CREATE INDEX idx_member_is_active ON group_member(isActive);
CREATE INDEX idx_member_role ON group_member(role);
-- 预约表索引
CREATE INDEX idx_appointment_group ON appointment(groupId);
CREATE INDEX idx_appointment_creator ON appointment(initiatorId);
CREATE INDEX idx_appointment_date ON appointment(eventDate);
CREATE INDEX idx_appointment_status ON appointment(status);
CREATE INDEX idx_appointment_created_at ON appointment(createdAt);
-- 预约参与者表索引
CREATE INDEX idx_participant_appointment ON appointment_participant(appointmentId);
CREATE INDEX idx_participant_user ON appointment_participant(userId);
-- 游戏表索引
CREATE INDEX idx_game_name ON game(name);
CREATE INDEX idx_game_category ON game(category);
-- 黑名单表索引
CREATE INDEX idx_blacklist_reporter ON blacklist(reporterId);
CREATE INDEX idx_blacklist_reported ON blacklist(reportedUserId);
CREATE INDEX idx_blacklist_status ON blacklist(status);
-- 荣誉墙表索引
CREATE INDEX idx_honors_group ON honors(groupId);
CREATE INDEX idx_honors_creator ON honors(creatorId);
CREATE INDEX idx_honors_year ON honors(year);
-- 积分表索引
CREATE INDEX idx_points_user ON points(userId);
CREATE INDEX idx_points_type ON points(type);
CREATE INDEX idx_points_created_at ON points(createdAt);
-- 打赌表索引
CREATE INDEX idx_bets_creator ON bets(creatorId);
CREATE INDEX idx_bets_status ON bets(status);
CREATE INDEX idx_bets_deadline ON bets(deadline);
数据库备份
# 手动备份
mysqldump -u root -p gamegroup > backup_$(date +%Y%m%d_%H%M%S).sql
# 恢复备份
mysql -u root -p gamegroup < backup_20240101_120000.sql
# 使用 Docker 备份
docker exec gamegroup-mysql-prod mysqldump -u root -p密码 gamegroup > backup.sql
# 定时备份(添加到 crontab)
0 2 * * * mysqldump -u root -p密码 gamegroup > /backups/gamegroup_$(date +\%Y\%m\%d).sql
性能优化建议
1. 应用层优化
启用 HTTP 压缩
已在 main.ts 中配置,确保 .env 中设置:
ENABLE_COMPRESSION=true
缓存配置优化
根据实际流量调整缓存参数:
# 高流量场景
CACHE_TTL=600 # 10分钟
CACHE_MAX=5000 # 5000条缓存
# 中等流量
CACHE_TTL=300 # 5分钟
CACHE_MAX=1000 # 1000条缓存
# 低流量
CACHE_TTL=180 # 3分钟
CACHE_MAX=500 # 500条缓存
连接池优化
在 database.config.ts 中已配置:
- 开发环境:10个连接
- 生产环境:20个连接
可根据服务器配置调整。
2. 数据库优化
查询缓存
生产环境已启用数据库查询缓存(1分钟)。
慢查询日志
-- 启用慢查询日志
SET GLOBAL slow_query_log = 'ON';
SET GLOBAL long_query_time = 2;
SET GLOBAL slow_query_log_file = '/var/log/mysql/slow-query.log';
-- 查看慢查询统计
SHOW STATUS LIKE 'Slow_queries';
定期优化表
-- 优化所有表
OPTIMIZE TABLE user, `group`, group_member, appointment;
-- 分析表
ANALYZE TABLE user, `group`, group_member;
3. 服务器配置优化
Nginx 反向代理(推荐)
upstream backend {
server localhost:3000;
# 如果有多个实例,添加更多服务器
# server localhost:3001;
# server localhost:3002;
}
server {
listen 80;
server_name your-domain.com;
# 请求体大小限制
client_max_body_size 10M;
# Gzip 压缩
gzip on;
gzip_types text/plain text/css application/json application/javascript;
gzip_min_length 1000;
location / {
proxy_pass http://backend;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
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_cache_bypass $http_upgrade;
# 超时设置
proxy_connect_timeout 60s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
}
# API 限流
location /api/ {
limit_req zone=api burst=20 nodelay;
proxy_pass http://backend;
}
}
# 限流配置(在 http 块中)
limit_req_zone $binary_remote_addr zone=api:10m rate=10r/s;
监控和维护
1. 健康检查端点
# 应用健康检查
curl http://localhost:3000/health
# 期望响应
{"status": "ok"}
2. 日志管理
查看应用日志
# Docker 环境
docker-compose -f docker-compose.prod.yml logs -f backend
# PM2 环境
pm2 logs gamegroup-backend
# 查看错误日志
pm2 logs gamegroup-backend --err
# 查看输出日志
pm2 logs gamegroup-backend --out
日志轮转配置
PM2 日志轮转:
# 安装 PM2 日志轮转模块
pm2 install pm2-logrotate
# 配置最大日志大小
pm2 set pm2-logrotate:max_size 10M
# 配置保留天数
pm2 set pm2-logrotate:retain 7
# 配置压缩
pm2 set pm2-logrotate:compress true
3. 性能监控
内置监控
# PM2 监控
pm2 monit
# 查看详细指标
pm2 show gamegroup-backend
推荐监控工具
- New Relic: 应用性能监控 (APM)
- Datadog: 全栈监控
- Prometheus + Grafana: 开源监控方案
- ELK Stack: 日志聚合和分析
4. 数据库监控
-- 查看连接数
SHOW STATUS LIKE 'Threads_connected';
-- 查看最大连接数
SHOW VARIABLES LIKE 'max_connections';
-- 查看查询统计
SHOW STATUS LIKE 'Questions';
SHOW STATUS LIKE 'Queries';
-- 查看慢查询
SHOW STATUS LIKE 'Slow_queries';
-- 查看当前运行的查询
SHOW PROCESSLIST;
常见问题排查
1. 应用无法启动
检查端口占用
# Windows
netstat -ano | findstr :3000
# Linux/Mac
lsof -i :3000
检查环境变量
# 确认环境变量已加载
echo $NODE_ENV
# 检查配置文件
cat .env.production
查看详细错误
# Docker
docker-compose -f docker-compose.prod.yml logs backend
# PM2
pm2 logs gamegroup-backend --lines 100
2. 数据库连接失败
检查数据库服务
# 检查 MySQL 是否运行
# Windows
sc query MySQL80
# Linux
systemctl status mysql
# Docker
docker ps | grep mysql
测试数据库连接
mysql -h localhost -u gamegroup -p -D gamegroup
常见错误
- ER_ACCESS_DENIED_ERROR: 用户名或密码错误
- ECONNREFUSED: 数据库服务未启动或端口错误
- ER_BAD_DB_ERROR: 数据库不存在
3. 内存占用过高
查看内存使用
# PM2
pm2 show gamegroup-backend
# Docker
docker stats gamegroup-backend-prod
解决方案
# PM2 设置内存限制(在 ecosystem.config.js 中)
max_memory_restart: '500M'
# 重启应用释放内存
pm2 restart gamegroup-backend
4. 性能问题
分析慢查询
-- 查看慢查询日志
SELECT * FROM mysql.slow_log;
-- 使用 EXPLAIN 分析查询
EXPLAIN SELECT * FROM user WHERE username = 'test';
检查缓存命中率
查看应用日志,搜索 "Cache hit" 和 "Cache miss"。
数据库优化
-- 检查表状态
SHOW TABLE STATUS LIKE 'user';
-- 优化表
OPTIMIZE TABLE user;
-- 更新统计信息
ANALYZE TABLE user;
5. Docker 相关问题
容器无法启动
# 查看容器日志
docker logs gamegroup-backend-prod
# 检查容器状态
docker inspect gamegroup-backend-prod
# 重新构建
docker-compose -f docker-compose.prod.yml build --no-cache
数据持久化问题
# 查看数据卷
docker volume ls
# 检查数据卷
docker volume inspect gamegroup_mysql-data
# 备份数据卷
docker run --rm -v gamegroup_mysql-data:/data -v $(pwd):/backup ubuntu tar czf /backup/mysql-backup.tar.gz /data
安全建议
1. 环境变量安全
- ✅ 不要将
.env文件提交到 Git - ✅ 使用强密码(至少16位,包含大小写字母、数字、特殊字符)
- ✅ 定期更换 JWT_SECRET
- ✅ 限制 CORS_ORIGIN 为实际域名
2. 数据库安全
- ✅ 不使用 root 用户连接
- ✅ 限制数据库用户权限(不给 DROP、ALTER 等危险权限)
- ✅ 使用防火墙限制数据库端口访问
- ✅ 启用 SSL/TLS 连接
3. 应用安全
- ✅ 定期更新依赖包:
npm audit fix - ✅ 启用 HTTPS(使用 Let's Encrypt 免费证书)
- ✅ 实施请求速率限制
- ✅ 设置 HTTP 安全头(Helmet 中间件)
- ✅ 输入验证和 SQL 注入防护(已使用 TypeORM)
4. 网络安全
# 配置防火墙(Ubuntu/Debian)
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw allow 22/tcp
sudo ufw deny 3306/tcp # 拒绝外部访问数据库
sudo ufw enable
# 仅允许特定 IP 访问数据库
sudo ufw allow from 服务器IP to any port 3306
升级和回滚
应用升级
# 1. 拉取最新代码
git pull origin main
# 2. 安装依赖
npm ci
# 3. 运行测试
npm test
# 4. 构建应用
npm run build:prod
# 5. 备份数据库
mysqldump -u root -p gamegroup > backup_before_upgrade.sql
# 6. 使用 PM2 重载(零停机)
pm2 reload gamegroup-backend
# 或使用 Docker
docker-compose -f docker-compose.prod.yml up -d --build
应用回滚
# 1. 切换到上一个版本
git checkout 上一个稳定版本的commit
# 2. 重新构建和部署
npm ci
npm run build:prod
pm2 restart gamegroup-backend
# 3. 如需回滚数据库
mysql -u root -p gamegroup < backup_before_upgrade.sql
生产环境检查清单
部署前请确认以下项目:
- 已设置强 JWT_SECRET
- 已设置强数据库密码
- DB_SYNCHRONIZE 设置为 false
- DB_LOGGING 设置为 false
- CORS_ORIGIN 限制为实际域名
- 已创建数据库索引
- 已配置数据库备份
- 已设置日志轮转
- 已配置监控告警
- 已进行压力测试
- 已准备回滚方案
- 已配置 HTTPS
- 已设置防火墙规则
- 已配置健康检查
- 已测试备份恢复流程
技术支持
文档参考
- NestJS 官方文档: https://docs.nestjs.com/
- TypeORM 文档: https://typeorm.io/
- PM2 文档: https://pm2.keymetrics.io/
- Docker 文档: https://docs.docker.com/
问题反馈
如遇到部署问题,请提供:
- 错误日志(完整堆栈跟踪)
- 环境信息(Node.js、MySQL 版本)
- 配置文件(隐藏敏感信息)
- 复现步骤
祝部署顺利! 🚀