feat: 完成Rust User API完整开发
Some checks failed
Deploy to Production / Run Tests (push) Failing after 16m35s
Deploy to Production / Security Scan (push) Has been skipped
Deploy to Production / Build Docker Image (push) Has been skipped
Deploy to Production / Deploy to Staging (push) Has been skipped
Deploy to Production / Deploy to Production (push) Has been skipped
Deploy to Production / Notify Results (push) Successful in 31s

 新功能:
- SQLite数据库集成和持久化存储
- 数据库迁移系统和版本管理
- API分页功能和高效查询
- 用户搜索和过滤机制
- 完整的RBAC角色权限系统
- 结构化日志记录和系统监控
- API限流和多层安全防护
- Docker容器化和生产部署配置

🔒 安全特性:
- JWT认证和授权
- 限流和防暴力破解
- 安全头和CORS配置
- 输入验证和XSS防护
- 审计日志和安全监控

📊 监控和运维:
- Prometheus指标收集
- 健康检查和系统监控
- 自动化备份和恢复
- 完整的运维文档和脚本
- CI/CD流水线配置

🚀 部署支持:
- 多环境Docker配置
- 生产环境部署指南
- 性能优化和安全加固
- 故障排除和应急响应
- 自动化运维脚本

📚 文档完善:
- API使用文档
- 部署检查清单
- 运维操作手册
- 性能和安全指南
- 故障排除指南
This commit is contained in:
2025-08-07 16:03:32 +08:00
parent cf01d557b9
commit bb9d7a869d
45 changed files with 8433 additions and 85 deletions

View File

@@ -0,0 +1,363 @@
# 生产环境部署检查清单
## 📋 部署前检查清单
### 🔧 系统环境检查
- [ ] **服务器规格确认**
- [ ] CPU: 至少2核心
- [ ] 内存: 至少2GB RAM
- [ ] 存储: 至少20GB可用空间
- [ ] 网络: 稳定的互联网连接
- [ ] **操作系统配置**
- [ ] Ubuntu 20.04+ 或 CentOS 8+ 或 Debian 11+
- [ ] 系统已更新到最新版本
- [ ] 时区设置正确
- [ ] NTP时间同步已启用
- [ ] **Docker环境**
- [ ] Docker Engine 20.10+ 已安装
- [ ] Docker Compose 2.0+ 已安装
- [ ] Docker服务正常运行
- [ ] 当前用户已加入docker组
### 🔒 安全配置检查
- [ ] **防火墙配置**
- [ ] UFW或iptables已配置
- [ ] 仅开放必要端口 (22, 80, 443)
- [ ] SSH端口已修改可选但推荐
- [ ] 禁用root用户SSH登录
- [ ] **SSL/TLS证书**
- [ ] SSL证书已准备Let's Encrypt或商业证书
- [ ] 证书文件权限正确设置
- [ ] 证书有效期检查
- [ ] 自动续期配置Let's Encrypt
- [ ] **用户权限**
- [ ] 创建专用的非特权用户
- [ ] 应用目录权限正确设置
- [ ] 敏感文件权限限制
### 📁 文件和配置检查
- [ ] **项目文件**
- [ ] 源代码已上传到服务器
- [ ] 文件权限正确设置
- [ ] .env.production文件已创建并配置
- [ ] 敏感信息已从代码中移除
- [ ] **配置文件**
- [ ] docker-compose.prod.yml已配置
- [ ] Nginx配置文件已准备
- [ ] 监控配置文件已准备
- [ ] 日志配置正确
### 🗄️ 数据库准备
- [ ] **数据库配置**
- [ ] 数据库连接字符串正确
- [ ] 数据库文件目录已创建
- [ ] 数据库权限正确设置
- [ ] 备份策略已制定
- [ ] **迁移脚本**
- [ ] 数据库迁移脚本已准备
- [ ] 迁移脚本已测试
- [ ] 回滚方案已准备
## 🚀 部署执行检查清单
### 1⃣ 环境准备
- [ ] **创建目录结构**
```bash
sudo mkdir -p /opt/rust-api/{data,logs,backups,ssl,config}
sudo mkdir -p /opt/rust-api/nginx/{conf.d,ssl}
sudo mkdir -p /opt/rust-api/monitoring/{prometheus,grafana}
```
- [ ] **设置权限**
```bash
sudo useradd -r -s /bin/false -m -d /opt/rust-api apiuser
sudo chown -R apiuser:apiuser /opt/rust-api
sudo chmod 750 /opt/rust-api
```
- [ ] **复制项目文件**
```bash
sudo cp -r /path/to/project/* /opt/rust-api/
sudo chown -R apiuser:apiuser /opt/rust-api
```
### 2⃣ 配置文件设置
- [ ] **环境变量配置**
```bash
sudo cp config/production.env.template /opt/rust-api/.env.production
sudo nano /opt/rust-api/.env.production # 编辑配置
sudo chmod 600 /opt/rust-api/.env.production
```
- [ ] **SSL证书配置**
```bash
sudo cp /path/to/cert.pem /opt/rust-api/ssl/
sudo cp /path/to/key.pem /opt/rust-api/ssl/
sudo chmod 600 /opt/rust-api/ssl/*.pem
```
- [ ] **Nginx配置**
```bash
sudo cp nginx/nginx.conf /opt/rust-api/nginx/
sudo chown apiuser:apiuser /opt/rust-api/nginx/nginx.conf
```
### 3⃣ 服务启动
- [ ] **构建镜像**
```bash
cd /opt/rust-api
sudo docker-compose -f docker-compose.prod.yml build
```
- [ ] **启动服务**
```bash
sudo docker-compose -f docker-compose.prod.yml up -d
```
- [ ] **检查服务状态**
```bash
sudo docker-compose -f docker-compose.prod.yml ps
sudo docker-compose -f docker-compose.prod.yml logs
```
### 4⃣ 功能验证
- [ ] **健康检查**
```bash
curl -f http://localhost/health
curl -f https://yourdomain.com/health
```
- [ ] **API端点测试**
```bash
# 测试用户注册
curl -X POST https://yourdomain.com/api/auth/register \
-H "Content-Type: application/json" \
-d '{"username":"testuser","email":"test@example.com","password":"TestPass123!"}'
# 测试用户登录
curl -X POST https://yourdomain.com/api/auth/login \
-H "Content-Type: application/json" \
-d '{"email":"test@example.com","password":"TestPass123!"}'
# 测试用户列表
curl -H "Authorization: Bearer YOUR_TOKEN" https://yourdomain.com/api/users
```
- [ ] **监控端点测试**
```bash
curl https://yourdomain.com/monitoring/health
curl https://yourdomain.com/monitoring/metrics/prometheus
```
## 📊 部署后验证检查清单
### 🔍 系统监控验证
- [ ] **服务状态检查**
- [ ] 所有容器正常运行
- [ ] 内存使用率正常 (<80%)
- [ ] CPU使用率正常 (<70%)
- [ ] 磁盘空间充足 (>20%可用)
- [ ] **网络连接检查**
- [ ] HTTP重定向到HTTPS正常
- [ ] SSL证书验证通过
- [ ] 域名解析正确
- [ ] 负载均衡器配置正确(如有)
- [ ] **日志检查**
- [ ] 应用日志正常输出
- [ ] 错误日志无异常
- [ ] 访问日志记录正常
- [ ] 审计日志功能正常
### 🛡️ 安全验证
- [ ] **安全扫描**
- [ ] SSL Labs测试通过 (A级以上)
- [ ] 安全头检查通过
- [ ] 端口扫描无异常开放端口
- [ ] 漏洞扫描无高危漏洞
- [ ] **访问控制验证**
- [ ] 未授权访问被正确拒绝
- [ ] JWT令牌验证正常
- [ ] 角色权限控制正常
- [ ] 限流机制正常工作
- [ ] **数据保护验证**
- [ ] 敏感数据加密存储
- [ ] 数据库访问权限正确
- [ ] 备份功能正常
- [ ] 数据恢复测试通过
### 📈 性能验证
- [ ] **响应时间测试**
- [ ] API响应时间 <200ms (95%请求)
- [ ] 数据库查询时间 <100ms
- [ ] 静态资源加载时间 <1s
- [ ] **并发测试**
- [ ] 100并发用户测试通过
- [ ] 1000并发用户测试通过可选
- [ ] 内存泄漏检查通过
- [ ] 连接池正常工作
- [ ] **压力测试**
```bash
# 使用Apache Bench进行压力测试
ab -n 1000 -c 10 https://yourdomain.com/api/users
# 使用wrk进行压力测试
wrk -t12 -c400 -d30s https://yourdomain.com/api/users
```
## 🔧 故障排除检查清单
### 🚨 常见问题诊断
- [ ] **服务无法启动**
- [ ] 检查Docker服务状态
- [ ] 检查端口占用情况
- [ ] 检查配置文件语法
- [ ] 检查文件权限
- [ ] **数据库连接失败**
- [ ] 检查数据库文件权限
- [ ] 检查连接字符串配置
- [ ] 检查数据库文件是否存在
- [ ] 检查磁盘空间
- [ ] **SSL证书问题**
- [ ] 检查证书文件路径
- [ ] 检查证书有效期
- [ ] 检查证书权限
- [ ] 检查域名匹配
- [ ] **性能问题**
- [ ] 检查系统资源使用
- [ ] 检查数据库查询性能
- [ ] 检查网络延迟
- [ ] 检查缓存配置
### 🔧 调试工具
- [ ] **日志查看命令**
```bash
# 查看应用日志
sudo docker-compose -f docker-compose.prod.yml logs -f rust-user-api
# 查看Nginx日志
sudo docker-compose -f docker-compose.prod.yml logs -f nginx
# 查看系统日志
sudo journalctl -u docker -f
```
- [ ] **性能监控命令**
```bash
# 查看容器资源使用
sudo docker stats
# 查看系统资源
htop
iotop
nethogs
# 查看网络连接
netstat -tulpn
ss -tulpn
```
- [ ] **数据库调试**
```bash
# 进入数据库容器
sudo docker-compose -f docker-compose.prod.yml exec rust-user-api sqlite3 /app/data/production.db
# 检查数据库完整性
PRAGMA integrity_check;
# 查看数据库统计
PRAGMA table_info(users);
```
## 📝 部署记录
### 部署信息记录
- **部署日期**: _______________
- **部署版本**: _______________
- **部署人员**: _______________
- **服务器信息**: _______________
- **域名**: _______________
### 配置参数记录
- **数据库类型**: _______________
- **SSL证书类型**: _______________
- **监控配置**: _______________
- **备份策略**: _______________
### 测试结果记录
- **功能测试**: ✅ / ❌
- **性能测试**: ✅ / ❌
- **安全测试**: ✅ / ❌
- **监控测试**: ✅ / ❌
### 问题和解决方案
| 问题描述 | 解决方案 | 状态 |
|---------|---------|------|
| | | |
| | | |
| | | |
## 📞 应急联系信息
### 技术支持
- **主要联系人**: _______________
- **电话**: _______________
- **邮箱**: _______________
- **备用联系人**: _______________
### 服务商信息
- **云服务商**: _______________
- **域名注册商**: _______________
- **SSL证书提供商**: _______________
- **监控服务商**: _______________
## 📚 相关文档
- [ ] [生产环境部署指南](production-deployment.md)
- [ ] [性能优化和安全加固指南](performance-security-guide.md)
- [ ] [Docker部署文档](../README-Docker.md)
- [ ] [API文档](../README.md)
- [ ] [故障排除指南](troubleshooting.md)
---
**注意**:
1. 请按照检查清单逐项验证,确保每个步骤都已完成
2. 遇到问题时,请参考故障排除部分或联系技术支持
3. 部署完成后,请保存此检查清单作为部署记录
4. 定期审查和更新此检查清单以适应新的需求
**部署完成签名**: _______________ **日期**: _______________

340
docs/docker-deployment.md Normal file
View File

@@ -0,0 +1,340 @@
# Docker 容器化部署指南
## 概述
本文档介绍如何使用Docker容器化部署Rust User API应用。
## 文件结构
```
.
├── Dockerfile # Docker镜像构建文件
├── docker-compose.yml # 完整的Docker Compose配置包含监控
├── docker-compose.simple.yml # 简化的Docker Compose配置仅应用
├── .dockerignore # Docker构建忽略文件
└── docs/
└── docker-deployment.md # 本文档
```
## 快速开始
### 1. 简单部署(推荐)
使用简化配置快速启动应用:
```bash
# 构建并启动应用
docker-compose -f docker-compose.simple.yml up --build
# 后台运行
docker-compose -f docker-compose.simple.yml up -d --build
```
应用将在 `http://localhost:3000` 启动。
### 2. 完整部署(包含监控)
使用完整配置启动应用和监控服务:
```bash
# 仅启动主应用
docker-compose up rust-user-api --build
# 启动应用和监控服务
docker-compose --profile monitoring up --build
```
服务端口:
- 应用: `http://localhost:3000`
- Prometheus: `http://localhost:9090`
- Grafana: `http://localhost:3001` (admin/admin123)
## Docker镜像特性
### 多阶段构建
- **构建阶段**: 使用 `rust:1.88-slim` 编译应用
- **运行阶段**: 使用 `debian:bookworm-slim` 运行应用
- **优化**: 最小化最终镜像大小
### 安全特性
- 使用非root用户运行应用
- 最小权限原则
- 安全的文件权限设置
### 健康检查
内置健康检查机制:
```dockerfile
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
CMD curl -f http://localhost:3000/health || exit 1
```
## 环境变量配置
### 核心配置
| 变量名 | 默认值 | 描述 |
|--------|--------|------|
| `RUST_LOG` | `info` | 日志级别 |
| `DATABASE_URL` | `sqlite:///app/data/users.db?mode=rwc` | 数据库连接字符串 |
| `SERVER_HOST` | `0.0.0.0` | 服务器监听地址 |
| `SERVER_PORT` | `3000` | 服务器端口 |
### 日志配置
| 变量名 | 默认值 | 描述 |
|--------|--------|------|
| `LOG_LEVEL` | `info` | 日志级别 |
| `LOG_FORMAT` | `pretty` | 日志格式 |
| `LOG_TO_CONSOLE` | `true` | 控制台输出 |
| `LOG_TO_FILE` | `false` | 文件输出 |
## 数据持久化
### 数据卷
应用使用Docker卷持久化数据
```yaml
volumes:
api_data:
driver: local
```
数据存储位置:
- 容器内: `/app/data/`
- SQLite数据库: `/app/data/users.db`
### 备份数据
```bash
# 备份数据卷
docker run --rm -v rust-server_api_data:/data -v $(pwd):/backup alpine tar czf /backup/api_data_backup.tar.gz -C /data .
# 恢复数据卷
docker run --rm -v rust-server_api_data:/data -v $(pwd):/backup alpine tar xzf /backup/api_data_backup.tar.gz -C /data
```
## 常用命令
### 构建和运行
```bash
# 构建镜像
docker build -t rust-user-api .
# 运行容器
docker run -p 3000:3000 rust-user-api
# 使用环境变量
docker run -p 3000:3000 -e RUST_LOG=debug rust-user-api
```
### 管理服务
```bash
# 查看服务状态
docker-compose ps
# 查看日志
docker-compose logs rust-user-api
# 重启服务
docker-compose restart rust-user-api
# 停止服务
docker-compose down
# 停止并删除数据卷
docker-compose down -v
```
### 调试和维护
```bash
# 进入容器
docker-compose exec rust-user-api /bin/bash
# 查看容器资源使用
docker stats rust-user-api
# 查看容器详细信息
docker inspect rust-user-api
```
## 监控和日志
### 应用监控
访问内置监控端点:
- 健康检查: `GET /health`
- 系统指标: `GET /monitoring/metrics/system`
- 应用指标: `GET /monitoring/metrics/app`
- 监控仪表板: `GET /monitoring/dashboard`
### 日志查看
```bash
# 实时查看日志
docker-compose logs -f rust-user-api
# 查看最近100行日志
docker-compose logs --tail=100 rust-user-api
# 查看特定时间段日志
docker-compose logs --since="2024-01-01T00:00:00" rust-user-api
```
## 生产环境部署
### 安全建议
1. **环境变量管理**
```bash
# 使用.env文件管理敏感信息
echo "DATABASE_URL=sqlite:///app/data/production.db" > .env
echo "JWT_SECRET=your-production-secret" >> .env
```
2. **网络安全**
```yaml
# 限制端口暴露
ports:
- "127.0.0.1:3000:3000" # 仅本地访问
```
3. **资源限制**
```yaml
deploy:
resources:
limits:
cpus: '1.0'
memory: 512M
reservations:
cpus: '0.5'
memory: 256M
```
### 性能优化
1. **镜像优化**
- 使用多阶段构建减小镜像大小
- 利用Docker层缓存加速构建
- 使用.dockerignore排除不必要文件
2. **运行时优化**
- 配置适当的健康检查间隔
- 设置合理的重启策略
- 使用专用网络隔离服务
## 故障排除
### 常见问题
1. **端口冲突**
```bash
# 检查端口占用
netstat -tulpn | grep :3000
# 修改端口映射
ports:
- "3001:3000"
```
2. **权限问题**
```bash
# 检查文件权限
docker-compose exec rust-user-api ls -la /app/data/
# 修复权限
docker-compose exec rust-user-api chown -R appuser:appuser /app/data/
```
3. **数据库连接问题**
```bash
# 检查数据库文件
docker-compose exec rust-user-api ls -la /app/data/
# 查看数据库日志
docker-compose logs rust-user-api | grep -i database
```
### 调试模式
启用调试模式:
```yaml
environment:
- RUST_LOG=debug
- LOG_LEVEL=debug
```
## 更新和维护
### 应用更新
```bash
# 拉取最新代码
git pull origin main
# 重新构建并部署
docker-compose up --build -d
# 验证更新
curl http://localhost:3000/health
```
### 数据库迁移
```bash
# 备份数据
docker-compose exec rust-user-api cp /app/data/users.db /app/data/users.db.backup
# 应用迁移(如果需要)
docker-compose exec rust-user-api ./rust-user-api --migrate
# 验证数据完整性
docker-compose exec rust-user-api sqlite3 /app/data/users.db ".tables"
```
## 扩展配置
### 负载均衡
使用多个实例:
```yaml
services:
rust-user-api:
# ... 现有配置
deploy:
replicas: 3
```
### 外部数据库
连接外部PostgreSQL
```yaml
environment:
- DATABASE_URL=postgresql://user:password@db:5432/rust_api
```
### SSL/TLS
使用反向代理如Traefik或Nginx处理SSL终止。
## 总结
Docker容器化部署提供了
- ✅ 环境一致性
- ✅ 简化部署流程
- ✅ 易于扩展和维护
- ✅ 完整的监控和日志
- ✅ 生产环境就绪
选择适合的部署方式:
- **开发/测试**: 使用 `docker-compose.simple.yml`
- **生产环境**: 使用 `docker-compose.yml` 并启用监控

682
docs/operations-manual.md Normal file
View File

@@ -0,0 +1,682 @@
# 运维手册
## 📖 概述
本手册提供Rust User API生产环境的日常运维指导包括监控、维护、故障处理和最佳实践。
## 🔍 日常监控
### 1. 系统健康检查
#### 每日检查项目
```bash
#!/bin/bash
# daily-health-check.sh
echo "=== Rust User API 每日健康检查 ==="
echo "检查时间: $(date)"
echo
# 1. 服务状态检查
echo "1. 检查服务状态..."
docker-compose -f /opt/rust-api/docker-compose.prod.yml ps
# 2. 健康端点检查
echo "2. 检查健康端点..."
if curl -f -s http://localhost/health > /dev/null; then
echo "✅ 健康检查通过"
else
echo "❌ 健康检查失败"
fi
# 3. 系统资源检查
echo "3. 检查系统资源..."
echo "CPU使用率: $(top -bn1 | grep "Cpu(s)" | awk '{print $2}' | cut -d'%' -f1)"
echo "内存使用率: $(free | grep Mem | awk '{printf("%.1f%%"), $3/$2 * 100.0}')"
echo "磁盘使用率: $(df -h / | awk 'NR==2{printf "%s", $5}')"
# 4. 数据库检查
echo "4. 检查数据库..."
DB_SIZE=$(docker-compose -f /opt/rust-api/docker-compose.prod.yml exec -T rust-user-api \
sqlite3 /app/data/production.db "SELECT page_count * page_size as size FROM pragma_page_count(), pragma_page_size();" 2>/dev/null)
echo "数据库大小: $((DB_SIZE / 1024 / 1024)) MB"
# 5. 日志检查
echo "5. 检查错误日志..."
ERROR_COUNT=$(docker-compose -f /opt/rust-api/docker-compose.prod.yml logs --since=24h rust-user-api 2>/dev/null | grep -i error | wc -l)
echo "24小时内错误数量: $ERROR_COUNT"
# 6. 证书检查
echo "6. 检查SSL证书..."
CERT_DAYS=$(openssl x509 -in /opt/rust-api/ssl/cert.pem -noout -dates | grep notAfter | cut -d= -f2)
echo "证书过期时间: $CERT_DAYS"
echo
echo "=== 检查完成 ==="
```
#### 监控指标阈值
| 指标 | 正常范围 | 警告阈值 | 严重阈值 |
|------|----------|----------|----------|
| CPU使用率 | <50% | 50-80% | >80% |
| 内存使用率 | <70% | 70-85% | >85% |
| 磁盘使用率 | <80% | 80-90% | >90% |
| 响应时间 | <200ms | 200-500ms | >500ms |
| 错误率 | <1% | 1-5% | >5% |
### 2. 性能监控
#### 关键性能指标 (KPI)
```bash
# 获取性能指标脚本
#!/bin/bash
# performance-metrics.sh
echo "=== 性能指标报告 ==="
echo "时间: $(date)"
echo
# API响应时间
echo "1. API响应时间测试..."
for endpoint in "/health" "/api/users" "/monitoring/metrics"; do
response_time=$(curl -o /dev/null -s -w "%{time_total}" "http://localhost$endpoint")
echo " $endpoint: ${response_time}s"
done
# 并发测试
echo "2. 并发性能测试..."
ab -n 100 -c 10 -q http://localhost/api/users | grep "Requests per second\|Time per request"
# 数据库性能
echo "3. 数据库性能..."
docker-compose -f /opt/rust-api/docker-compose.prod.yml exec -T rust-user-api \
sqlite3 /app/data/production.db "PRAGMA optimize; PRAGMA integrity_check;"
echo "=== 报告完成 ==="
```
### 3. 日志监控
#### 日志分析脚本
```bash
#!/bin/bash
# log-analysis.sh
LOG_FILE="/opt/rust-api/logs/app.log"
HOURS=${1:-24}
echo "=== 最近${HOURS}小时日志分析 ==="
# 错误统计
echo "1. 错误统计:"
grep -i error $LOG_FILE | tail -n 100 | awk '{print $1, $2}' | sort | uniq -c | sort -nr
# 请求统计
echo "2. 请求统计:"
grep "http_request" $LOG_FILE | tail -n 1000 | \
grep -o '"method":"[^"]*"' | sort | uniq -c | sort -nr
# 响应时间分析
echo "3. 响应时间分析:"
grep "response_time" $LOG_FILE | tail -n 100 | \
grep -o '"response_time":[0-9]*' | cut -d: -f2 | \
awk '{sum+=$1; count++} END {if(count>0) print "平均响应时间:", sum/count "ms"}'
# IP访问统计
echo "4. 访问IP统计:"
grep "remote_addr" $LOG_FILE | tail -n 1000 | \
grep -o '"remote_addr":"[^"]*"' | cut -d: -f2 | tr -d '"' | \
sort | uniq -c | sort -nr | head -10
```
## 🔧 日常维护
### 1. 数据库维护
#### 数据库优化
```bash
#!/bin/bash
# database-maintenance.sh
echo "=== 数据库维护开始 ==="
# 1. 数据库优化
echo "1. 执行数据库优化..."
docker-compose -f /opt/rust-api/docker-compose.prod.yml exec -T rust-user-api \
sqlite3 /app/data/production.db "PRAGMA optimize; VACUUM; ANALYZE;"
# 2. 检查数据库完整性
echo "2. 检查数据库完整性..."
INTEGRITY=$(docker-compose -f /opt/rust-api/docker-compose.prod.yml exec -T rust-user-api \
sqlite3 /app/data/production.db "PRAGMA integrity_check;")
if [ "$INTEGRITY" = "ok" ]; then
echo "✅ 数据库完整性检查通过"
else
echo "❌ 数据库完整性检查失败: $INTEGRITY"
fi
# 3. 统计信息
echo "3. 数据库统计信息..."
docker-compose -f /opt/rust-api/docker-compose.prod.yml exec -T rust-user-api \
sqlite3 /app/data/production.db << 'EOF'
.mode column
.headers on
SELECT 'users' as table_name, COUNT(*) as record_count FROM users;
SELECT 'user_sessions' as table_name, COUNT(*) as record_count FROM user_sessions;
EOF
echo "=== 数据库维护完成 ==="
```
#### 数据备份
```bash
#!/bin/bash
# backup-database.sh
BACKUP_DIR="/opt/rust-api/backups"
DATE=$(date +%Y%m%d-%H%M%S)
RETENTION_DAYS=30
echo "=== 数据库备份开始 ==="
# 1. 创建备份目录
mkdir -p $BACKUP_DIR
# 2. 备份数据库
echo "1. 备份数据库..."
docker-compose -f /opt/rust-api/docker-compose.prod.yml exec -T rust-user-api \
sqlite3 /app/data/production.db ".backup /app/data/backup-$DATE.db"
# 3. 复制到主机
docker cp rust-user-api-prod:/app/data/backup-$DATE.db $BACKUP_DIR/
# 4. 压缩备份
echo "2. 压缩备份文件..."
tar -czf "$BACKUP_DIR/database-backup-$DATE.tar.gz" \
-C $BACKUP_DIR backup-$DATE.db
# 5. 清理临时文件
rm -f "$BACKUP_DIR/backup-$DATE.db"
# 6. 验证备份
echo "3. 验证备份..."
if [ -f "$BACKUP_DIR/database-backup-$DATE.tar.gz" ]; then
SIZE=$(du -h "$BACKUP_DIR/database-backup-$DATE.tar.gz" | cut -f1)
echo "✅ 备份成功: database-backup-$DATE.tar.gz ($SIZE)"
else
echo "❌ 备份失败"
exit 1
fi
# 7. 清理旧备份
echo "4. 清理旧备份..."
find $BACKUP_DIR -name "database-backup-*.tar.gz" -mtime +$RETENTION_DAYS -delete
REMAINING=$(find $BACKUP_DIR -name "database-backup-*.tar.gz" | wc -l)
echo "保留备份数量: $REMAINING"
echo "=== 数据库备份完成 ==="
```
### 2. 日志管理
#### 日志轮转
```bash
#!/bin/bash
# log-rotation.sh
LOG_DIR="/opt/rust-api/logs"
MAX_SIZE="100M"
MAX_FILES=10
echo "=== 日志轮转开始 ==="
# 1. 检查日志大小
for log_file in "$LOG_DIR"/*.log; do
if [ -f "$log_file" ]; then
size=$(du -h "$log_file" | cut -f1)
echo "日志文件: $(basename $log_file) - 大小: $size"
# 如果文件大于最大大小,进行轮转
if [ $(du -m "$log_file" | cut -f1) -gt 100 ]; then
echo "轮转日志: $log_file"
# 压缩并重命名旧日志
timestamp=$(date +%Y%m%d-%H%M%S)
gzip -c "$log_file" > "${log_file}.${timestamp}.gz"
# 清空当前日志文件
> "$log_file"
echo "✅ 日志轮转完成: ${log_file}.${timestamp}.gz"
fi
fi
done
# 2. 清理旧日志
echo "2. 清理旧日志文件..."
find $LOG_DIR -name "*.log.*.gz" -mtime +30 -delete
echo "=== 日志轮转完成 ==="
```
### 3. 系统清理
#### 系统清理脚本
```bash
#!/bin/bash
# system-cleanup.sh
echo "=== 系统清理开始 ==="
# 1. Docker清理
echo "1. 清理Docker资源..."
docker system prune -f
docker volume prune -f
docker image prune -f
# 2. 清理临时文件
echo "2. 清理临时文件..."
find /tmp -type f -mtime +7 -delete 2>/dev/null || true
find /var/tmp -type f -mtime +7 -delete 2>/dev/null || true
# 3. 清理系统日志
echo "3. 清理系统日志..."
journalctl --vacuum-time=30d
journalctl --vacuum-size=1G
# 4. 更新系统包
echo "4. 更新系统包..."
apt update && apt upgrade -y
# 5. 检查磁盘空间
echo "5. 磁盘空间报告..."
df -h
echo "=== 系统清理完成 ==="
```
## 🚨 故障处理
### 1. 常见故障处理流程
#### 服务无响应
```bash
#!/bin/bash
# service-recovery.sh
echo "=== 服务恢复流程 ==="
# 1. 检查服务状态
echo "1. 检查服务状态..."
docker-compose -f /opt/rust-api/docker-compose.prod.yml ps
# 2. 检查健康端点
echo "2. 检查健康端点..."
if ! curl -f -s --max-time 10 http://localhost/health; then
echo "❌ 健康检查失败,开始恢复流程..."
# 3. 查看最近日志
echo "3. 查看最近日志..."
docker-compose -f /opt/rust-api/docker-compose.prod.yml logs --tail=50 rust-user-api
# 4. 重启服务
echo "4. 重启服务..."
docker-compose -f /opt/rust-api/docker-compose.prod.yml restart rust-user-api
# 5. 等待服务启动
echo "5. 等待服务启动..."
sleep 30
# 6. 再次检查
if curl -f -s --max-time 10 http://localhost/health; then
echo "✅ 服务恢复成功"
else
echo "❌ 服务恢复失败,需要人工介入"
exit 1
fi
else
echo "✅ 服务正常运行"
fi
echo "=== 恢复流程完成 ==="
```
#### 数据库问题处理
```bash
#!/bin/bash
# database-recovery.sh
echo "=== 数据库恢复流程 ==="
DB_PATH="/opt/rust-api/data/production.db"
BACKUP_DIR="/opt/rust-api/backups"
# 1. 检查数据库完整性
echo "1. 检查数据库完整性..."
INTEGRITY=$(docker-compose -f /opt/rust-api/docker-compose.prod.yml exec -T rust-user-api \
sqlite3 /app/data/production.db "PRAGMA integrity_check;" 2>/dev/null)
if [ "$INTEGRITY" != "ok" ]; then
echo "❌ 数据库完整性检查失败: $INTEGRITY"
# 2. 停止服务
echo "2. 停止服务..."
docker-compose -f /opt/rust-api/docker-compose.prod.yml stop rust-user-api
# 3. 备份损坏的数据库
echo "3. 备份损坏的数据库..."
cp $DB_PATH "${DB_PATH}.corrupted.$(date +%Y%m%d-%H%M%S)"
# 4. 恢复最新备份
echo "4. 恢复最新备份..."
LATEST_BACKUP=$(find $BACKUP_DIR -name "database-backup-*.tar.gz" | sort -r | head -1)
if [ -n "$LATEST_BACKUP" ]; then
echo "使用备份: $LATEST_BACKUP"
tar -xzf "$LATEST_BACKUP" -C /tmp/
cp /tmp/backup-*.db $DB_PATH
chown apiuser:apiuser $DB_PATH
echo "✅ 数据库恢复完成"
else
echo "❌ 未找到可用备份"
exit 1
fi
# 5. 重启服务
echo "5. 重启服务..."
docker-compose -f /opt/rust-api/docker-compose.prod.yml start rust-user-api
# 6. 验证恢复
sleep 30
if curl -f -s http://localhost/health; then
echo "✅ 服务恢复成功"
else
echo "❌ 服务恢复失败"
exit 1
fi
else
echo "✅ 数据库完整性正常"
fi
echo "=== 数据库恢复完成 ==="
```
### 2. 性能问题诊断
#### 性能诊断脚本
```bash
#!/bin/bash
# performance-diagnosis.sh
echo "=== 性能诊断开始 ==="
# 1. 系统资源使用
echo "1. 系统资源使用情况:"
echo "CPU: $(top -bn1 | grep "Cpu(s)" | awk '{print $2}')"
echo "内存: $(free -h | grep Mem | awk '{print $3 "/" $2}')"
echo "磁盘IO: $(iostat -x 1 1 | tail -n +4 | awk '{print $1, $10}' | grep -v '^$')"
# 2. 容器资源使用
echo "2. 容器资源使用:"
docker stats --no-stream --format "table {{.Container}}\t{{.CPUPerc}}\t{{.MemUsage}}\t{{.NetIO}}\t{{.BlockIO}}"
# 3. 数据库性能
echo "3. 数据库性能分析:"
docker-compose -f /opt/rust-api/docker-compose.prod.yml exec -T rust-user-api \
sqlite3 /app/data/production.db << 'EOF'
.timer on
SELECT COUNT(*) FROM users;
SELECT COUNT(*) FROM user_sessions WHERE created_at > datetime('now', '-1 day');
EOF
# 4. 网络连接
echo "4. 网络连接统计:"
netstat -an | grep :3000 | awk '{print $6}' | sort | uniq -c
# 5. 慢查询分析
echo "5. 慢查询分析:"
grep "slow_query" /opt/rust-api/logs/app.log | tail -10
echo "=== 性能诊断完成 ==="
```
## 📊 监控和告警
### 1. 监控配置
#### Prometheus告警规则
```yaml
# /opt/rust-api/monitoring/prometheus/alert-rules.yml
groups:
- name: rust-api-alerts
rules:
- alert: HighErrorRate
expr: rate(http_requests_total{status=~"5.."}[5m]) > 0.1
for: 5m
labels:
severity: warning
annotations:
summary: "High error rate detected"
description: "Error rate is {{ $value }} errors per second"
- alert: HighResponseTime
expr: histogram_quantile(0.95, rate(http_request_duration_seconds_bucket[5m])) > 1
for: 5m
labels:
severity: warning
annotations:
summary: "High response time detected"
description: "95th percentile response time is {{ $value }}s"
- alert: ServiceDown
expr: up{job="rust-user-api"} == 0
for: 1m
labels:
severity: critical
annotations:
summary: "Service is down"
description: "Rust User API service is not responding"
- alert: HighMemoryUsage
expr: (node_memory_MemTotal_bytes - node_memory_MemAvailable_bytes) / node_memory_MemTotal_bytes > 0.85
for: 5m
labels:
severity: warning
annotations:
summary: "High memory usage"
description: "Memory usage is {{ $value | humanizePercentage }}"
- alert: HighDiskUsage
expr: (node_filesystem_size_bytes - node_filesystem_avail_bytes) / node_filesystem_size_bytes > 0.85
for: 5m
labels:
severity: warning
annotations:
summary: "High disk usage"
description: "Disk usage is {{ $value | humanizePercentage }}"
```
### 2. 自动化运维
#### Crontab配置
```bash
# 添加到crontab: crontab -e
# 每小时执行健康检查
0 * * * * /opt/rust-api/scripts/daily-health-check.sh >> /var/log/health-check.log 2>&1
# 每天凌晨2点备份数据库
0 2 * * * /opt/rust-api/scripts/backup-database.sh >> /var/log/backup.log 2>&1
# 每天凌晨3点执行数据库维护
0 3 * * * /opt/rust-api/scripts/database-maintenance.sh >> /var/log/db-maintenance.log 2>&1
# 每周日凌晨4点执行系统清理
0 4 * * 0 /opt/rust-api/scripts/system-cleanup.sh >> /var/log/system-cleanup.log 2>&1
# 每天检查日志大小并轮转
0 1 * * * /opt/rust-api/scripts/log-rotation.sh >> /var/log/log-rotation.log 2>&1
# 每5分钟检查服务状态
*/5 * * * * /opt/rust-api/scripts/service-monitor.sh >> /var/log/service-monitor.log 2>&1
```
#### 服务监控脚本
```bash
#!/bin/bash
# service-monitor.sh
ALERT_EMAIL="admin@yourdomain.com"
LOG_FILE="/var/log/service-monitor.log"
# 检查服务健康状态
if ! curl -f -s --max-time 10 http://localhost/health > /dev/null; then
echo "$(date): Service health check failed" >> $LOG_FILE
# 发送告警邮件
echo "Rust User API service health check failed at $(date)" | \
mail -s "Service Alert: API Health Check Failed" $ALERT_EMAIL
# 尝试自动恢复
/opt/rust-api/scripts/service-recovery.sh >> $LOG_FILE 2>&1
fi
# 检查系统资源
CPU_USAGE=$(top -bn1 | grep "Cpu(s)" | awk '{print $2}' | cut -d'%' -f1)
MEM_USAGE=$(free | grep Mem | awk '{printf("%.1f"), $3/$2 * 100.0}')
if (( $(echo "$CPU_USAGE > 80" | bc -l) )); then
echo "$(date): High CPU usage: $CPU_USAGE%" >> $LOG_FILE
fi
if (( $(echo "$MEM_USAGE > 85" | bc -l) )); then
echo "$(date): High memory usage: $MEM_USAGE%" >> $LOG_FILE
fi
```
## 📈 容量规划
### 1. 资源使用趋势分析
#### 资源统计脚本
```bash
#!/bin/bash
# resource-stats.sh
STATS_FILE="/opt/rust-api/logs/resource-stats.csv"
DATE=$(date '+%Y-%m-%d %H:%M:%S')
# 创建CSV头部如果文件不存在
if [ ! -f "$STATS_FILE" ]; then
echo "timestamp,cpu_usage,memory_usage,disk_usage,active_connections,response_time" > $STATS_FILE
fi
# 收集指标
CPU_USAGE=$(top -bn1 | grep "Cpu(s)" | awk '{print $2}' | cut -d'%' -f1)
MEM_USAGE=$(free | grep Mem | awk '{printf("%.1f"), $3/$2 * 100.0}')
DISK_USAGE=$(df -h / | awk 'NR==2{print $5}' | cut -d'%' -f1)
CONNECTIONS=$(netstat -an | grep :3000 | grep ESTABLISHED | wc -l)
RESPONSE_TIME=$(curl -o /dev/null -s -w "%{time_total}" http://localhost/health)
# 写入CSV
echo "$DATE,$CPU_USAGE,$MEM_USAGE,$DISK_USAGE,$CONNECTIONS,$RESPONSE_TIME" >> $STATS_FILE
# 保留最近30天的数据
tail -n 43200 $STATS_FILE > ${STATS_FILE}.tmp && mv ${STATS_FILE}.tmp $STATS_FILE
```
### 2. 扩容建议
#### 扩容决策矩阵
| 指标 | 当前阈值 | 扩容建议 |
|------|----------|----------|
| CPU使用率 > 70% | 增加CPU核心或横向扩展 |
| 内存使用率 > 80% | 增加内存或优化应用 |
| 磁盘使用率 > 85% | 扩展存储或数据归档 |
| 响应时间 > 500ms | 性能优化或负载均衡 |
| 并发连接 > 1000 | 增加实例或连接池优化 |
## 📞 应急响应
### 1. 应急联系流程
#### 故障等级定义
- **P0 (严重)**: 服务完全不可用,影响所有用户
- **P1 (高)**: 核心功能不可用,影响大部分用户
- **P2 (中)**: 部分功能不可用,影响少部分用户
- **P3 (低)**: 性能问题或非核心功能问题
#### 应急响应时间
- P0: 15分钟内响应1小时内解决
- P1: 30分钟内响应4小时内解决
- P2: 2小时内响应24小时内解决
- P3: 1个工作日内响应1周内解决
### 2. 应急处理清单
#### P0级别故障处理
```bash
#!/bin/bash
# emergency-response-p0.sh
echo "=== P0级别应急响应 ==="
echo "开始时间: $(date)"
# 1. 立即通知
echo "1. 发送紧急通知..."
echo "P0 Alert: Rust User API service is down" | \
mail -s "URGENT: Service Down" admin@yourdomain.com
# 2. 快速诊断
echo "2. 快速诊断..."
docker-compose -f /opt/rust-api/docker-compose.prod.yml ps
curl -I http://localhost/health
# 3. 尝试快速恢复
echo "3. 尝试快速恢复..."
docker-compose -f /opt/rust-api/docker-compose.prod.yml restart
# 4. 验证恢复
sleep 30
if curl -f -s http://localhost/health; then
echo "✅ 服务已恢复"
echo "Service recovered at $(date)" | \
mail -s "Service Recovered" admin@yourdomain.com
else
echo "❌ 快速恢复失败,需要深度诊断"
# 启动深度诊断流程
/opt/rust-api/scripts/deep-diagnosis.sh
fi
echo "=== 应急响应完成 ==="
```
## 📚 运维最佳实践
### 1. 预防性维护
- **定期备份**: 每日自动备份,每周验证备份完整性
- **监控告警**: 设置合理的告警阈值,避免告警疲劳
- **容量规划**: 定期评估资源使用趋势,提前扩容
- **安全更新**: 及时应用安全补丁和更新
- **文档维护**: 保持运维文档的及时更新
### 2. 变更管理
- **变更审批**: 所有生产环境变更需要审批
- **测试验证**: 变更前在测试环境充分验证
- **回滚计划**: 每次变更都要有明确的回滚方案
- **变更记录**: 详细记录所有变更内容和结果
### 3. 知识管理
- **故障记录**: 详细记录每次故障的原因和解决方案
- **经验分享**: 定期分享运维经验和最佳实践
- **培训计划**: 定期进行运维技能培训
- **文档更新**: 及时更新运维手册和流程文档
---
**注意**: 本手册应根据实际运维需求定期更新和完善。所有脚本在使用前应在测试环境验证。

View File

@@ -0,0 +1,873 @@
# 性能优化和安全加固指南
## 📈 性能优化
### 1. Rust应用优化
#### 编译优化
```toml
# Cargo.toml
[profile.release]
opt-level = 3 # 最高优化级别
lto = true # 链接时优化
codegen-units = 1 # 单个代码生成单元
panic = 'abort' # 减少二进制大小
strip = true # 移除调试符号
```
#### 内存优化
```rust
// src/config/performance.rs
use std::sync::Arc;
use tokio::sync::RwLock;
pub struct PerformanceConfig {
pub max_connections: usize,
pub connection_timeout: u64,
pub request_timeout: u64,
pub worker_threads: usize,
pub max_blocking_threads: usize,
}
impl Default for PerformanceConfig {
fn default() -> Self {
Self {
max_connections: 1000,
connection_timeout: 30,
request_timeout: 30,
worker_threads: num_cpus::get(),
max_blocking_threads: 512,
}
}
}
// 连接池优化
pub fn optimize_database_pool() -> sqlx::SqlitePool {
sqlx::sqlite::SqlitePoolOptions::new()
.max_connections(20)
.min_connections(5)
.acquire_timeout(std::time::Duration::from_secs(30))
.idle_timeout(std::time::Duration::from_secs(600))
.max_lifetime(std::time::Duration::from_secs(1800))
.build("sqlite://production.db")
.expect("Failed to create database pool")
}
```
#### 异步优化
```rust
// 使用批量操作减少数据库调用
pub async fn batch_create_users(
pool: &SqlitePool,
users: Vec<CreateUserRequest>,
) -> Result<Vec<User>, sqlx::Error> {
let mut tx = pool.begin().await?;
let mut created_users = Vec::new();
for user in users {
let created_user = sqlx::query_as!(
User,
"INSERT INTO users (username, email, password_hash) VALUES (?, ?, ?) RETURNING *",
user.username,
user.email,
user.password_hash
)
.fetch_one(&mut *tx)
.await?;
created_users.push(created_user);
}
tx.commit().await?;
Ok(created_users)
}
// 使用流式处理大量数据
use futures::StreamExt;
pub async fn stream_users(pool: &SqlitePool) -> impl Stream<Item = Result<User, sqlx::Error>> {
sqlx::query_as!(User, "SELECT * FROM users")
.fetch(pool)
}
```
### 2. 数据库优化
#### SQLite优化配置
```sql
-- 性能优化设置
PRAGMA journal_mode = WAL; -- 写前日志模式
PRAGMA synchronous = NORMAL; -- 平衡性能和安全
PRAGMA cache_size = 1000000; -- 1GB缓存
PRAGMA temp_store = memory; -- 临时表存储在内存
PRAGMA mmap_size = 268435456; -- 256MB内存映射
PRAGMA optimize; -- 优化查询计划
-- 索引优化
CREATE INDEX IF NOT EXISTS idx_users_email ON users(email);
CREATE INDEX IF NOT EXISTS idx_users_username ON users(username);
CREATE INDEX IF NOT EXISTS idx_users_created_at ON users(created_at);
CREATE INDEX IF NOT EXISTS idx_users_role ON users(role);
-- 复合索引
CREATE INDEX IF NOT EXISTS idx_users_role_created ON users(role, created_at);
CREATE INDEX IF NOT EXISTS idx_users_active_email ON users(is_active, email) WHERE is_active = 1;
```
#### 查询优化
```rust
// 使用预编译语句
pub struct OptimizedQueries {
find_user_by_email: sqlx::query::Query<'static, sqlx::Sqlite, sqlx::sqlite::SqliteArguments<'static>>,
find_users_paginated: sqlx::query::Query<'static, sqlx::Sqlite, sqlx::sqlite::SqliteArguments<'static>>,
}
impl OptimizedQueries {
pub fn new() -> Self {
Self {
find_user_by_email: sqlx::query_as!(
User,
"SELECT * FROM users WHERE email = ? LIMIT 1"
),
find_users_paginated: sqlx::query_as!(
User,
"SELECT * FROM users ORDER BY created_at DESC LIMIT ? OFFSET ?"
),
}
}
}
// 使用连接查询减少数据库往返
pub async fn get_user_with_profile(
pool: &SqlitePool,
user_id: i64,
) -> Result<UserWithProfile, sqlx::Error> {
sqlx::query_as!(
UserWithProfile,
r#"
SELECT
u.id, u.username, u.email, u.created_at,
p.bio, p.avatar_url, p.location
FROM users u
LEFT JOIN user_profiles p ON u.id = p.user_id
WHERE u.id = ?
"#,
user_id
)
.fetch_one(pool)
.await
}
```
### 3. 缓存策略
#### Redis缓存实现
```rust
// src/cache/redis.rs
use redis::{Client, Connection, RedisResult};
use serde::{Deserialize, Serialize};
use std::time::Duration;
pub struct RedisCache {
client: Client,
}
impl RedisCache {
pub fn new(redis_url: &str) -> RedisResult<Self> {
let client = Client::open(redis_url)?;
Ok(Self { client })
}
pub async fn get<T>(&self, key: &str) -> RedisResult<Option<T>>
where
T: for<'de> Deserialize<'de>,
{
let mut conn = self.client.get_async_connection().await?;
let value: Option<String> = redis::cmd("GET").arg(key).query_async(&mut conn).await?;
match value {
Some(json) => Ok(Some(serde_json::from_str(&json).map_err(|_| {
redis::RedisError::from((redis::ErrorKind::TypeError, "JSON parse error"))
})?)),
None => Ok(None),
}
}
pub async fn set<T>(&self, key: &str, value: &T, ttl: Duration) -> RedisResult<()>
where
T: Serialize,
{
let mut conn = self.client.get_async_connection().await?;
let json = serde_json::to_string(value).map_err(|_| {
redis::RedisError::from((redis::ErrorKind::TypeError, "JSON serialize error"))
})?;
redis::cmd("SETEX")
.arg(key)
.arg(ttl.as_secs())
.arg(json)
.query_async(&mut conn)
.await
}
}
// 缓存装饰器
pub async fn cached_get_user(
cache: &RedisCache,
pool: &SqlitePool,
user_id: i64,
) -> Result<User, AppError> {
let cache_key = format!("user:{}", user_id);
// 尝试从缓存获取
if let Ok(Some(user)) = cache.get::<User>(&cache_key).await {
return Ok(user);
}
// 从数据库获取
let user = get_user_by_id(pool, user_id).await?;
// 存入缓存
let _ = cache.set(&cache_key, &user, Duration::from_secs(300)).await;
Ok(user)
}
```
#### 内存缓存
```rust
// src/cache/memory.rs
use std::collections::HashMap;
use std::sync::Arc;
use std::time::{Duration, Instant};
use tokio::sync::RwLock;
pub struct MemoryCache<T> {
data: Arc<RwLock<HashMap<String, CacheEntry<T>>>>,
default_ttl: Duration,
}
struct CacheEntry<T> {
value: T,
expires_at: Instant,
}
impl<T: Clone> MemoryCache<T> {
pub fn new(default_ttl: Duration) -> Self {
Self {
data: Arc::new(RwLock::new(HashMap::new())),
default_ttl,
}
}
pub async fn get(&self, key: &str) -> Option<T> {
let data = self.data.read().await;
if let Some(entry) = data.get(key) {
if entry.expires_at > Instant::now() {
return Some(entry.value.clone());
}
}
None
}
pub async fn set(&self, key: String, value: T) {
let expires_at = Instant::now() + self.default_ttl;
let entry = CacheEntry { value, expires_at };
let mut data = self.data.write().await;
data.insert(key, entry);
}
pub async fn cleanup_expired(&self) {
let mut data = self.data.write().await;
let now = Instant::now();
data.retain(|_, entry| entry.expires_at > now);
}
}
```
### 4. HTTP优化
#### 连接池和超时配置
```rust
// src/server/config.rs
use axum::http::HeaderValue;
use tower::ServiceBuilder;
use tower_http::{
compression::CompressionLayer,
cors::CorsLayer,
timeout::TimeoutLayer,
trace::TraceLayer,
};
pub fn create_optimized_app() -> Router {
Router::new()
.layer(
ServiceBuilder::new()
.layer(TraceLayer::new_for_http())
.layer(CompressionLayer::new())
.layer(TimeoutLayer::new(Duration::from_secs(30)))
.layer(
CorsLayer::new()
.allow_origin("https://yourdomain.com".parse::<HeaderValue>().unwrap())
.allow_methods([Method::GET, Method::POST, Method::PUT, Method::DELETE])
.allow_headers([AUTHORIZATION, CONTENT_TYPE])
.max_age(Duration::from_secs(3600))
)
)
}
// 连接保持配置
pub fn create_server() -> Result<Server<AddrIncoming, Router>, Box<dyn std::error::Error>> {
let addr = SocketAddr::from(([0, 0, 0, 0], 3000));
Server::bind(&addr)
.http1_keepalive(true)
.http1_half_close(true)
.http2_keep_alive_interval(Some(Duration::from_secs(30)))
.http2_keep_alive_timeout(Duration::from_secs(10))
.serve(app.into_make_service())
}
```
## 🔒 安全加固
### 1. 应用层安全
#### 输入验证和清理
```rust
// src/validation/security.rs
use regex::Regex;
use once_cell::sync::Lazy;
static EMAIL_REGEX: Lazy<Regex> = Lazy::new(|| {
Regex::new(r"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$").unwrap()
});
static USERNAME_REGEX: Lazy<Regex> = Lazy::new(|| {
Regex::new(r"^[a-zA-Z0-9_]{3,20}$").unwrap()
});
pub fn validate_email(email: &str) -> Result<(), ValidationError> {
if email.len() > 254 {
return Err(ValidationError::new("email_too_long"));
}
if !EMAIL_REGEX.is_match(email) {
return Err(ValidationError::new("invalid_email_format"));
}
Ok(())
}
pub fn validate_username(username: &str) -> Result<(), ValidationError> {
if !USERNAME_REGEX.is_match(username) {
return Err(ValidationError::new("invalid_username"));
}
// 检查是否包含敏感词
let forbidden_words = ["admin", "root", "system", "api"];
if forbidden_words.iter().any(|&word| username.to_lowercase().contains(word)) {
return Err(ValidationError::new("forbidden_username"));
}
Ok(())
}
// SQL注入防护
pub fn sanitize_sql_input(input: &str) -> String {
input
.replace("'", "''")
.replace("\"", "\"\"")
.replace(";", "")
.replace("--", "")
.replace("/*", "")
.replace("*/", "")
}
// XSS防护
pub fn sanitize_html(input: &str) -> String {
input
.replace("<", "&lt;")
.replace(">", "&gt;")
.replace("\"", "&quot;")
.replace("'", "&#x27;")
.replace("/", "&#x2F;")
}
```
#### 密码安全
```rust
// src/auth/password.rs
use argon2::{Argon2, PasswordHash, PasswordHasher, PasswordVerifier};
use argon2::password_hash::{rand_core::OsRng, SaltString};
use zxcvbn::zxcvbn;
pub struct PasswordSecurity;
impl PasswordSecurity {
pub fn hash_password(password: &str) -> Result<String, argon2::password_hash::Error> {
let salt = SaltString::generate(&mut OsRng);
let argon2 = Argon2::default();
let password_hash = argon2.hash_password(password.as_bytes(), &salt)?;
Ok(password_hash.to_string())
}
pub fn verify_password(password: &str, hash: &str) -> Result<bool, argon2::password_hash::Error> {
let parsed_hash = PasswordHash::new(hash)?;
let argon2 = Argon2::default();
Ok(argon2.verify_password(password.as_bytes(), &parsed_hash).is_ok())
}
pub fn check_password_strength(password: &str) -> Result<(), ValidationError> {
if password.len() < 8 {
return Err(ValidationError::new("password_too_short"));
}
if password.len() > 128 {
return Err(ValidationError::new("password_too_long"));
}
// 使用zxcvbn检查密码强度
let estimate = zxcvbn(password, &[]).unwrap();
if estimate.score() < 3 {
return Err(ValidationError::new("password_too_weak"));
}
// 检查字符类型
let has_lower = password.chars().any(|c| c.is_lowercase());
let has_upper = password.chars().any(|c| c.is_uppercase());
let has_digit = password.chars().any(|c| c.is_numeric());
let has_special = password.chars().any(|c| "!@#$%^&*()_+-=[]{}|;:,.<>?".contains(c));
let char_types = [has_lower, has_upper, has_digit, has_special]
.iter()
.filter(|&&x| x)
.count();
if char_types < 3 {
return Err(ValidationError::new("password_insufficient_complexity"));
}
Ok(())
}
}
```
#### JWT安全
```rust
// src/auth/jwt.rs
use jsonwebtoken::{decode, encode, Algorithm, DecodingKey, EncodingKey, Header, Validation};
use serde::{Deserialize, Serialize};
use std::time::{SystemTime, UNIX_EPOCH};
#[derive(Debug, Serialize, Deserialize)]
pub struct Claims {
pub sub: String,
pub exp: usize,
pub iat: usize,
pub iss: String,
pub aud: String,
pub jti: String,
pub role: String,
}
pub struct JwtSecurity {
encoding_key: EncodingKey,
decoding_key: DecodingKey,
validation: Validation,
}
impl JwtSecurity {
pub fn new(secret: &str) -> Self {
let mut validation = Validation::new(Algorithm::HS256);
validation.set_issuer(&["rust-user-api"]);
validation.set_audience(&["api-users"]);
validation.leeway = 60; // 1分钟时钟偏差容忍
Self {
encoding_key: EncodingKey::from_secret(secret.as_ref()),
decoding_key: DecodingKey::from_secret(secret.as_ref()),
validation,
}
}
pub fn create_token(&self, user_id: &str, role: &str) -> Result<String, jsonwebtoken::errors::Error> {
let now = SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_secs() as usize;
let exp = now + 3600; // 1小时过期
let claims = Claims {
sub: user_id.to_string(),
exp,
iat: now,
iss: "rust-user-api".to_string(),
aud: "api-users".to_string(),
jti: uuid::Uuid::new_v4().to_string(), // JWT ID防重放
role: role.to_string(),
};
encode(&Header::default(), &claims, &self.encoding_key)
}
pub fn verify_token(&self, token: &str) -> Result<Claims, jsonwebtoken::errors::Error> {
let token_data = decode::<Claims>(token, &self.decoding_key, &self.validation)?;
Ok(token_data.claims)
}
}
```
### 2. 网络层安全
#### TLS配置
```rust
// src/server/tls.rs
use rustls::{Certificate, PrivateKey, ServerConfig};
use rustls_pemfile::{certs, pkcs8_private_keys};
use std::fs::File;
use std::io::BufReader;
pub fn load_tls_config(cert_path: &str, key_path: &str) -> Result<ServerConfig, Box<dyn std::error::Error>> {
let cert_file = &mut BufReader::new(File::open(cert_path)?);
let key_file = &mut BufReader::new(File::open(key_path)?);
let cert_chain = certs(cert_file)?
.into_iter()
.map(Certificate)
.collect();
let mut keys: Vec<PrivateKey> = pkcs8_private_keys(key_file)?
.into_iter()
.map(PrivateKey)
.collect();
if keys.is_empty() {
return Err("No private key found".into());
}
let config = ServerConfig::builder()
.with_safe_default_cipher_suites()
.with_safe_default_kx_groups()
.with_safe_default_protocol_versions()?
.with_no_client_auth()
.with_single_cert(cert_chain, keys.remove(0))?;
Ok(config)
}
```
#### 安全头中间件
```rust
// src/middleware/security_headers.rs
use axum::{
http::{header, HeaderMap, HeaderValue, Request, Response},
middleware::Next,
response::IntoResponse,
};
pub async fn security_headers<B>(
request: Request<B>,
next: Next<B>,
) -> impl IntoResponse {
let mut response = next.run(request).await;
let headers = response.headers_mut();
// HSTS
headers.insert(
header::STRICT_TRANSPORT_SECURITY,
HeaderValue::from_static("max-age=31536000; includeSubDomains; preload"),
);
// CSP
headers.insert(
header::CONTENT_SECURITY_POLICY,
HeaderValue::from_static("default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'"),
);
// X-Frame-Options
headers.insert(
header::X_FRAME_OPTIONS,
HeaderValue::from_static("DENY"),
);
// X-Content-Type-Options
headers.insert(
header::X_CONTENT_TYPE_OPTIONS,
HeaderValue::from_static("nosniff"),
);
// X-XSS-Protection
headers.insert(
HeaderValue::from_static("x-xss-protection"),
HeaderValue::from_static("1; mode=block"),
);
// Referrer Policy
headers.insert(
HeaderValue::from_static("referrer-policy"),
HeaderValue::from_static("strict-origin-when-cross-origin"),
);
// Permissions Policy
headers.insert(
HeaderValue::from_static("permissions-policy"),
HeaderValue::from_static("geolocation=(), microphone=(), camera=()"),
);
response
}
```
### 3. 数据库安全
#### 连接安全
```rust
// src/database/security.rs
use sqlx::{sqlite::SqliteConnectOptions, ConnectOptions, SqlitePool};
use std::str::FromStr;
pub async fn create_secure_pool(database_url: &str) -> Result<SqlitePool, sqlx::Error> {
let mut options = SqliteConnectOptions::from_str(database_url)?
.create_if_missing(true)
.journal_mode(sqlx::sqlite::SqliteJournalMode::Wal)
.synchronous(sqlx::sqlite::SqliteSynchronous::Normal)
.busy_timeout(std::time::Duration::from_secs(30))
.pragma("cache_size", "1000000")
.pragma("temp_store", "memory")
.pragma("mmap_size", "268435456");
// 禁用不安全的功能
options = options
.pragma("trusted_schema", "OFF")
.pragma("defensive", "ON");
// 设置日志级别
options.log_statements(log::LevelFilter::Debug);
SqlitePool::connect_with(options).await
}
// 数据加密
pub fn encrypt_sensitive_data(data: &str, key: &[u8]) -> Result<String, Box<dyn std::error::Error>> {
use aes_gcm::{Aes256Gcm, Key, Nonce};
use aes_gcm::aead::{Aead, NewAead};
use rand::Rng;
let cipher = Aes256Gcm::new(Key::from_slice(key));
let nonce_bytes: [u8; 12] = rand::thread_rng().gen();
let nonce = Nonce::from_slice(&nonce_bytes);
let ciphertext = cipher.encrypt(nonce, data.as_bytes())?;
// 组合nonce和密文
let mut result = nonce_bytes.to_vec();
result.extend_from_slice(&ciphertext);
Ok(base64::encode(result))
}
pub fn decrypt_sensitive_data(encrypted_data: &str, key: &[u8]) -> Result<String, Box<dyn std::error::Error>> {
use aes_gcm::{Aes256Gcm, Key, Nonce};
use aes_gcm::aead::{Aead, NewAead};
let data = base64::decode(encrypted_data)?;
if data.len() < 12 {
return Err("Invalid encrypted data".into());
}
let (nonce_bytes, ciphertext) = data.split_at(12);
let cipher = Aes256Gcm::new(Key::from_slice(key));
let nonce = Nonce::from_slice(nonce_bytes);
let plaintext = cipher.decrypt(nonce, ciphertext)?;
Ok(String::from_utf8(plaintext)?)
}
```
### 4. 监控和审计
#### 安全事件监控
```rust
// src/security/monitoring.rs
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use std::sync::Arc;
use tokio::sync::RwLock;
#[derive(Debug, Serialize, Deserialize)]
pub struct SecurityEvent {
pub event_type: SecurityEventType,
pub timestamp: chrono::DateTime<chrono::Utc>,
pub source_ip: String,
pub user_id: Option<String>,
pub details: HashMap<String, String>,
pub severity: SecuritySeverity,
}
#[derive(Debug, Serialize, Deserialize)]
pub enum SecurityEventType {
LoginAttempt,
LoginFailure,
BruteForceDetected,
SuspiciousActivity,
UnauthorizedAccess,
DataBreach,
SystemIntrusion,
}
#[derive(Debug, Serialize, Deserialize)]
pub enum SecuritySeverity {
Low,
Medium,
High,
Critical,
}
pub struct SecurityMonitor {
events: Arc<RwLock<Vec<SecurityEvent>>>,
alert_thresholds: HashMap<SecurityEventType, usize>,
}
impl SecurityMonitor {
pub fn new() -> Self {
let mut thresholds = HashMap::new();
thresholds.insert(SecurityEventType::LoginFailure, 5);
thresholds.insert(SecurityEventType::BruteForceDetected, 1);
thresholds.insert(SecurityEventType::UnauthorizedAccess, 3);
Self {
events: Arc::new(RwLock::new(Vec::new())),
alert_thresholds: thresholds,
}
}
pub async fn log_event(&self, event: SecurityEvent) {
let mut events = self.events.write().await;
events.push(event.clone());
// 检查是否需要触发告警
if self.should_alert(&event).await {
self.send_alert(&event).await;
}
// 清理旧事件保留最近1000个
if events.len() > 1000 {
events.drain(0..events.len() - 1000);
}
}
async fn should_alert(&self, event: &SecurityEvent) -> bool {
if let Some(&threshold) = self.alert_thresholds.get(&event.event_type) {
let events = self.events.read().await;
let recent_events = events
.iter()
.filter(|e| {
e.event_type == event.event_type
&& e.source_ip == event.source_ip
&& e.timestamp > chrono::Utc::now() - chrono::Duration::hours(1)
})
.count();
return recent_events >= threshold;
}
matches!(event.severity, SecuritySeverity::Critical)
}
async fn send_alert(&self, event: &SecurityEvent) {
// 发送告警通知
log::error!("Security Alert: {:?}", event);
// 这里可以集成邮件、短信、Slack等通知方式
// send_email_alert(event).await;
// send_slack_alert(event).await;
}
}
```
### 5. 部署安全
#### Docker安全配置
```dockerfile
# 安全的Dockerfile
FROM rust:1.88-slim as builder
# 创建非特权用户
RUN groupadd -r rustuser && useradd -r -g rustuser rustuser
WORKDIR /app
COPY . .
RUN cargo build --release
FROM debian:bookworm-slim
# 安装安全更新
RUN apt-get update && apt-get upgrade -y && \
apt-get install -y --no-install-recommends \
ca-certificates \
sqlite3 \
libssl3 \
curl && \
rm -rf /var/lib/apt/lists/* && \
apt-get clean
# 创建非特权用户
RUN groupadd -r apiuser && useradd -r -g apiuser apiuser
# 创建应用目录
RUN mkdir -p /app/data /app/logs && \
chown -R apiuser:apiuser /app
# 复制二进制文件
COPY --from=builder /app/target/release/rust-user-api /app/
COPY --from=builder /app/migrations /app/migrations/
# 设置权限
RUN chmod +x /app/rust-user-api && \
chown apiuser:apiuser /app/rust-user-api
# 切换到非特权用户
USER apiuser
# 健康检查
HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \
CMD curl -f http://localhost:3000/health || exit 1
EXPOSE 3000
CMD ["/app/rust-user-api"]
```
#### 系统安全配置
```bash
#!/bin/bash
# security-hardening.sh
# 系统安全加固脚本
# 1. 更新系统
apt update && apt upgrade -y
# 2. 安装安全工具
apt install -y fail2ban ufw rkhunter chkrootkit
# 3. 配置防火墙
ufw default deny incoming
ufw default allow outgoing
ufw allow ssh
ufw allow 80/tcp
ufw allow 443/tcp
ufw --force enable
# 4. 配置fail2ban
cat > /etc/fail2ban/jail.local << 'EOF'
[DEFAULT]
bantime = 3600
findtime = 600
maxretry = 5
[sshd]
enabled = true
port = ssh
logpath = /var/log/auth.log
maxret

View File

@@ -0,0 +1,608 @@
# 生产环境部署指南
## 概述
本文档提供Rust User API在生产环境中的完整部署指南包括安全配置、性能优化、监控设置和运维最佳实践。
## 🏗️ 架构概览
### 推荐架构
```
Internet
[Load Balancer/CDN]
[Reverse Proxy (Nginx/Traefik)]
[Rust User API Containers]
[SQLite/PostgreSQL Database]
```
### 组件说明
- **负载均衡器**: 分发流量,提供高可用性
- **反向代理**: SSL终止静态文件服务安全过滤
- **应用容器**: 多实例部署,水平扩展
- **数据库**: 持久化存储,支持备份恢复
## 🔧 生产环境配置
### 1. 环境变量配置
创建生产环境配置文件:
```bash
# .env.production
# 服务器配置
SERVER_HOST=0.0.0.0
SERVER_PORT=3000
RUST_LOG=info
# 数据库配置
DATABASE_URL=sqlite:///app/data/production.db?mode=rwc
# 或使用PostgreSQL
# DATABASE_URL=postgresql://user:password@db:5432/rust_api
# 安全配置
JWT_SECRET=your-super-secure-jwt-secret-key-change-this
SECURITY_RATE_LIMIT_PER_MINUTE=100
SECURITY_BRUTE_FORCE_MAX_ATTEMPTS=5
SECURITY_BAN_DURATION=3600
# 日志配置
LOG_LEVEL=info
LOG_FORMAT=json
LOG_TO_CONSOLE=true
LOG_TO_FILE=true
LOG_FILE_PATH=/app/logs/app.log
# 监控配置
METRICS_ENABLED=true
HEALTH_CHECK_ENABLED=true
```
### 2. Docker Compose 生产配置
```yaml
# docker-compose.prod.yml
version: '3.8'
services:
rust-user-api:
build:
context: .
dockerfile: Dockerfile
image: rust-user-api:latest
container_name: rust-user-api-prod
restart: always
ports:
- "127.0.0.1:3000:3000" # 仅本地访问
environment:
- RUST_LOG=info
- DATABASE_URL=sqlite:///app/data/production.db?mode=rwc
- JWT_SECRET=${JWT_SECRET}
- LOG_FORMAT=json
- LOG_TO_FILE=true
volumes:
- api_data:/app/data
- api_logs:/app/logs
networks:
- api_network
deploy:
resources:
limits:
cpus: '2.0'
memory: 1G
reservations:
cpus: '0.5'
memory: 256M
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:3000/health"]
interval: 30s
timeout: 10s
retries: 3
start_period: 40s
logging:
driver: "json-file"
options:
max-size: "100m"
max-file: "5"
nginx:
image: nginx:alpine
container_name: nginx-proxy
restart: always
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro
- ./nginx/ssl:/etc/nginx/ssl:ro
- api_logs:/var/log/api:ro
depends_on:
- rust-user-api
networks:
- api_network
volumes:
api_data:
driver: local
api_logs:
driver: local
networks:
api_network:
driver: bridge
```
### 3. Nginx 反向代理配置
```nginx
# nginx/nginx.conf
events {
worker_connections 1024;
}
http {
upstream rust_api {
server rust-user-api:3000;
# 多实例负载均衡
# server rust-user-api-2:3000;
# server rust-user-api-3:3000;
}
# 限流配置
limit_req_zone $binary_remote_addr zone=api:10m rate=10r/s;
limit_conn_zone $binary_remote_addr zone=conn_limit_per_ip:10m;
server {
listen 80;
server_name your-domain.com;
# 重定向到HTTPS
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
server_name your-domain.com;
# SSL配置
ssl_certificate /etc/nginx/ssl/cert.pem;
ssl_certificate_key /etc/nginx/ssl/key.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512;
ssl_prefer_server_ciphers off;
# 安全头
add_header X-Frame-Options DENY;
add_header X-Content-Type-Options nosniff;
add_header X-XSS-Protection "1; mode=block";
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload";
# 限流
limit_req zone=api burst=20 nodelay;
limit_conn conn_limit_per_ip 10;
# API代理
location /api/ {
proxy_pass http://rust_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 /health {
proxy_pass http://rust_api;
access_log off;
}
# 监控端点(限制访问)
location /monitoring/ {
allow 10.0.0.0/8;
allow 172.16.0.0/12;
allow 192.168.0.0/16;
deny all;
proxy_pass http://rust_api;
}
}
}
```
## 🔒 安全配置
### 1. SSL/TLS 证书
```bash
# 使用Let's Encrypt获取免费证书
certbot --nginx -d your-domain.com
# 或使用自签名证书(仅测试)
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
-keyout nginx/ssl/key.pem \
-out nginx/ssl/cert.pem
```
### 2. 防火墙配置
```bash
# UFW配置示例
ufw default deny incoming
ufw default allow outgoing
ufw allow ssh
ufw allow 80/tcp
ufw allow 443/tcp
ufw enable
```
### 3. 系统安全
```bash
# 创建专用用户
useradd -r -s /bin/false -m -d /opt/rust-api apiuser
# 设置文件权限
chown -R apiuser:apiuser /opt/rust-api
chmod 750 /opt/rust-api
```
## 📊 监控和日志
### 1. Prometheus 配置
```yaml
# monitoring/prometheus.yml
global:
scrape_interval: 15s
scrape_configs:
- job_name: 'rust-user-api'
static_configs:
- targets: ['rust-user-api:3000']
metrics_path: '/monitoring/metrics/prometheus'
scrape_interval: 30s
- job_name: 'nginx'
static_configs:
- targets: ['nginx:9113']
```
### 2. Grafana 仪表板
```json
{
"dashboard": {
"title": "Rust User API Dashboard",
"panels": [
{
"title": "Request Rate",
"type": "graph",
"targets": [
{
"expr": "rate(http_requests_total[5m])"
}
]
},
{
"title": "Response Time",
"type": "graph",
"targets": [
{
"expr": "histogram_quantile(0.95, rate(http_request_duration_seconds_bucket[5m]))"
}
]
}
]
}
}
```
### 3. 日志聚合
```yaml
# docker-compose.logging.yml
version: '3.8'
services:
elasticsearch:
image: docker.elastic.co/elasticsearch/elasticsearch:7.15.0
environment:
- discovery.type=single-node
volumes:
- es_data:/usr/share/elasticsearch/data
logstash:
image: docker.elastic.co/logstash/logstash:7.15.0
volumes:
- ./logstash/pipeline:/usr/share/logstash/pipeline
- api_logs:/logs
kibana:
image: docker.elastic.co/kibana/kibana:7.15.0
ports:
- "5601:5601"
environment:
- ELASTICSEARCH_HOSTS=http://elasticsearch:9200
volumes:
es_data:
```
## 🚀 部署流程
### 1. 自动化部署脚本
```bash
#!/bin/bash
# deploy.sh
set -e
echo "🚀 开始部署 Rust User API..."
# 1. 拉取最新代码
git pull origin main
# 2. 构建镜像
docker-compose -f docker-compose.prod.yml build --no-cache
# 3. 备份数据库
docker-compose -f docker-compose.prod.yml exec rust-user-api \
cp /app/data/production.db /app/data/backup-$(date +%Y%m%d-%H%M%S).db
# 4. 停止旧服务
docker-compose -f docker-compose.prod.yml down
# 5. 启动新服务
docker-compose -f docker-compose.prod.yml up -d
# 6. 健康检查
sleep 30
if curl -f http://localhost/health; then
echo "✅ 部署成功!"
else
echo "❌ 部署失败,回滚..."
docker-compose -f docker-compose.prod.yml down
# 这里可以添加回滚逻辑
exit 1
fi
echo "🎉 部署完成!"
```
### 2. CI/CD 流水线
```yaml
# .github/workflows/deploy.yml
name: Deploy to Production
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Setup Docker
uses: docker/setup-buildx-action@v1
- name: Build and test
run: |
docker build -t rust-user-api:test .
docker run --rm rust-user-api:test cargo test
- name: Deploy to production
run: |
ssh ${{ secrets.PROD_SERVER }} 'cd /opt/rust-api && ./deploy.sh'
```
## 📈 性能优化
### 1. 数据库优化
```sql
-- SQLite优化
PRAGMA journal_mode = WAL;
PRAGMA synchronous = NORMAL;
PRAGMA cache_size = 1000000;
PRAGMA temp_store = memory;
```
### 2. 应用优化
```toml
# Cargo.toml 生产优化
[profile.release]
opt-level = 3
lto = true
codegen-units = 1
panic = 'abort'
```
### 3. 容器优化
```dockerfile
# 多阶段构建优化
FROM rust:1.88-slim as builder
# ... 构建阶段
FROM debian:bookworm-slim
# 安装运行时依赖
RUN apt-get update && apt-get install -y \
ca-certificates \
sqlite3 \
libssl3 \
curl \
&& rm -rf /var/lib/apt/lists/* \
&& apt-get clean
```
## 🔧 运维管理
### 1. 备份策略
```bash
#!/bin/bash
# backup.sh
BACKUP_DIR="/opt/backups"
DATE=$(date +%Y%m%d-%H%M%S)
# 数据库备份
docker-compose exec rust-user-api \
sqlite3 /app/data/production.db ".backup /app/data/backup-$DATE.db"
# 压缩备份
tar -czf "$BACKUP_DIR/api-backup-$DATE.tar.gz" \
-C /opt/rust-api/data backup-$DATE.db
# 清理旧备份保留30天
find $BACKUP_DIR -name "api-backup-*.tar.gz" -mtime +30 -delete
```
### 2. 监控告警
```yaml
# alertmanager.yml
groups:
- name: rust-api-alerts
rules:
- alert: HighErrorRate
expr: rate(http_requests_total{status=~"5.."}[5m]) > 0.1
for: 5m
annotations:
summary: "High error rate detected"
- alert: HighResponseTime
expr: histogram_quantile(0.95, rate(http_request_duration_seconds_bucket[5m])) > 1
for: 5m
annotations:
summary: "High response time detected"
```
### 3. 日常维护
```bash
# 系统维护脚本
#!/bin/bash
# 清理Docker资源
docker system prune -f
# 更新系统包
apt update && apt upgrade -y
# 检查磁盘空间
df -h
# 检查服务状态
docker-compose ps
systemctl status docker
```
## 🔍 故障排除
### 1. 常见问题
| 问题 | 症状 | 解决方案 |
|------|------|----------|
| 内存不足 | 容器重启 | 增加内存限制,优化代码 |
| 数据库锁定 | 请求超时 | 检查并发连接,优化查询 |
| SSL证书过期 | HTTPS错误 | 更新证书,配置自动续期 |
| 磁盘空间不足 | 写入失败 | 清理日志,扩展存储 |
### 2. 调试工具
```bash
# 查看容器日志
docker-compose logs -f rust-user-api
# 进入容器调试
docker-compose exec rust-user-api /bin/bash
# 检查网络连接
docker network ls
docker network inspect rust-server_api_network
# 监控资源使用
docker stats
htop
iotop
```
## 📋 检查清单
### 部署前检查
- [ ] 环境变量配置正确
- [ ] SSL证书有效
- [ ] 防火墙规则配置
- [ ] 数据库备份完成
- [ ] 监控系统正常
- [ ] 负载测试通过
### 部署后验证
- [ ] 健康检查通过
- [ ] API端点响应正常
- [ ] 日志记录正常
- [ ] 监控指标正常
- [ ] 安全扫描通过
- [ ] 性能测试达标
## 🎯 最佳实践
### 1. 安全最佳实践
- 使用强密码和密钥
- 定期更新依赖包
- 启用审计日志
- 实施最小权限原则
- 定期安全扫描
### 2. 性能最佳实践
- 启用HTTP/2
- 使用CDN加速
- 实施缓存策略
- 优化数据库查询
- 监控关键指标
### 3. 运维最佳实践
- 自动化部署流程
- 实施蓝绿部署
- 定期备份数据
- 监控系统健康
- 建立应急响应计划
---
## 📞 支持和维护
### 联系信息
- 技术支持: tech-support@company.com
- 紧急联系: +86-xxx-xxxx-xxxx
- 文档更新: docs@company.com
### 更新日志
- v1.0.0: 初始生产环境配置
- v1.1.0: 添加监控和告警
- v1.2.0: 优化性能和安全配置
---
**注意**: 本文档应根据实际生产环境需求进行调整和定制。定期审查和更新配置以确保最佳的安全性和性能。

201
docs/security-features.md Normal file
View File

@@ -0,0 +1,201 @@
# 安全中间件功能文档
## 概述
本项目实现了全面的API安全中间件系统包括限流、安全检查、安全头设置和认证失败处理等功能。
## 主要功能
### 1. 限流中间件 (Rate Limiting)
- **功能**: 基于IP地址的请求频率限制
- **默认配置**: 每分钟60个请求
- **实现**: 使用 `governor` crate 实现令牌桶算法
- **特性**:
- 基于IP地址的独立限流
- 可配置的请求频率
- 自动清理过期记录
### 2. 安全检查中间件 (Security Check)
- **功能**: 检测和阻止可疑请求模式
- **检测模式**:
- SQL注入尝试 (`union`, `select`, `insert`, `update`, `delete`, `drop`, `create`, `alter`)
- XSS攻击 (`<script>`, `javascript:`, `vbscript:`, `onload=`, `onerror=`)
- 路径遍历 (`../`, `../\`, `/etc/`, `/proc/`, `/sys/`)
- 命令注入 (`cmd`, `exec`, `system`, `eval`, `base64_decode`)
- 敏感账户名 (`admin`, `root`, `administrator`, `sa`, `dbo`)
### 3. 安全头中间件 (Security Headers)
- **功能**: 自动添加安全相关的HTTP头
- **添加的头**:
- `X-Content-Type-Options: nosniff`
- `X-Frame-Options: DENY`
- `X-XSS-Protection: 1; mode=block`
- `Referrer-Policy: strict-origin-when-cross-origin`
- `Content-Security-Policy: default-src 'self'`
- `Permissions-Policy: geolocation=(), microphone=(), camera=()`
- **移除的头**: `Server`, `X-Powered-By`
### 4. 暴力破解检测
- **功能**: 检测和防止暴力破解攻击
- **配置**:
- 检测窗口: 5分钟
- 最大尝试次数: 5次
- 封禁时间: 1小时
- **触发条件**:
- 可疑请求模式
- 认证失败(登录相关端点)
### 5. IP封禁系统
- **功能**: 自动封禁恶意IP地址
- **特性**:
- 基于暴力破解检测的自动封禁
- 可配置的封禁时间
- 自动清理过期封禁记录
- 审计日志记录
### 6. JWT认证中间件
- **功能**: JWT令牌验证和用户认证
- **特性**:
- Bearer token 提取
- JWT签名验证
- 过期时间检查
- 用户ID注入到请求上下文
## 配置选项
```rust
pub struct SecurityConfig {
/// 每分钟请求限制
pub requests_per_minute: u32,
/// 暴力破解检测窗口(秒)
pub brute_force_window: u64,
/// 暴力破解最大尝试次数
pub brute_force_max_attempts: u32,
/// IP封禁时间
pub ban_duration: u64,
/// 启用CORS
pub enable_cors: bool,
/// 允许的源
pub allowed_origins: Vec<String>,
/// 启用安全头
pub enable_security_headers: bool,
/// 最大请求体大小(字节)
pub max_request_size: usize,
}
```
## 使用示例
### 基本集成
```rust
use rust_user_api::middleware::{SecurityConfig, SecurityState};
// 创建安全配置
let security_config = SecurityConfig::default();
let security_state = Arc::new(SecurityState::new(security_config));
// 应用中间件
let app = Router::new()
.layer(axum::middleware::from_fn_with_state(
security_state.clone(),
rate_limiting_middleware,
))
.layer(axum::middleware::from_fn_with_state(
security_state.clone(),
security_check_middleware,
))
.layer(axum::middleware::from_fn(
security_headers_middleware,
));
```
### JWT认证
```rust
use rust_user_api::middleware::{create_jwt, jwt_auth_middleware};
// 创建JWT token
let token = create_jwt("user_id_123")?;
// 应用JWT认证中间件
let protected_routes = Router::new()
.route("/protected", get(protected_handler))
.layer(axum::middleware::from_fn(jwt_auth_middleware));
```
## 监控和日志
### 审计日志
所有安全事件都会记录到审计日志中:
- 可疑请求模式检测
- IP封禁事件
- 限流触发
- 认证失败
### 指标收集
- 请求总数
- 错误率
- 平均响应时间
- 系统资源使用情况
## 安全最佳实践
1. **定期更新JWT密钥**: 在生产环境中使用强密钥并定期轮换
2. **监控审计日志**: 定期检查安全事件和异常模式
3. **调整限流参数**: 根据实际业务需求调整限流配置
4. **网络层防护**: 结合防火墙和CDN提供多层防护
5. **定期安全审计**: 定期检查和更新安全配置
## 性能考虑
- 使用高效的数据结构DashMap进行并发访问
- 自动清理过期记录避免内存泄漏
- 异步处理避免阻塞请求
- 可配置的检测模式减少不必要的计算
## 扩展性
系统设计支持:
- 自定义可疑模式
- 可插拔的认证方式
- 灵活的配置选项
- 多种存储后端支持
## 测试
项目包含全面的安全功能测试:
```bash
# 运行安全测试
cargo test security_tests
# 运行所有测试
cargo test
```
## 故障排除
### 常见问题
1. **限流过于严格**: 调整 `requests_per_minute` 参数
2. **误报可疑模式**: 检查和调整正则表达式模式
3. **JWT验证失败**: 检查密钥配置和token格式
4. **性能问题**: 监控内存使用和清理频率
### 调试技巧
- 启用详细日志记录
- 使用监控API检查系统状态
- 检查审计日志了解安全事件
- 使用测试工具验证配置