Files
NextEdu/docs/dr/dr-plan.md
SpecialX 6585e10c6f feat(P2): 实现质量保障类5项功能(无障碍/视觉回归/通知渠道/漏洞扫描/灾备)
## 新增功能

### 1. 屏幕阅读器兼容性增强(a11y)
- 无障碍工具库:src/shared/lib/a11y.ts
- aria-live Hook:src/shared/hooks/use-aria-live.ts
- a11y 组件:skip-link/visually-hidden/focus-trap/aria-status
- 增强 UI:table.tsx 系统性 ARIA role,dialog.tsx aria-modal
- 审计文档:docs/accessibility/a11y-audit.md(WCAG 2.1 AA 清单)

### 2. 视觉回归测试
- 测试套件:tests/visual/(homepage + 3 个 dashboard)
- 3 视口(desktop/tablet/mobile)× 2 主题(light/dark)
- 动态元素遮罩,避免误报
- playwright.config.ts 新增 visual-chromium 项目
- 文档:docs/testing/visual-regression.md

### 3. 短信/微信推送渠道集成
- 新模块:src/modules/notifications/
- 4 个渠道:SMS(阿里云/腾讯云)、WeChat(公众号)、Email(SMTP)、In-App
- 分发器按用户偏好并行多渠道发送
- 外部 SDK 动态 import,Mock 模式开发可用
- 文档:docs/notifications/channels.md

### 4. 漏洞扫描 CI 集成
- CI security-scan job:npm audit + Snyk + Trivy FS + OWASP ZAP
- 独立工作流 security.yml:每周一深度扫描 + 容器镜像扫描
- 配置:suppressions.json + .trivyignore
- 本地脚本:security-scan.sh/ps1
- 文档:docs/security/scanning.md(SLA 分级)

### 5. 灾备方案
- 脚本:backup-verify/backup-offsite-sync/dr-drill/failover/health-check
- CI 增强:备份后校验+异地同步,每周灾备演练
- 独立工作流 dr-drill.yml:每周一凌晨 4 点自动演练
- 文档:docs/dr/dr-plan.md(RTO 4h/RPO 24h)+ dr-runbook.md(6 故障场景)

## 验证
- npx tsc --noEmit:0 错误
- npm run lint:0 错误 0 警告
2026-06-17 20:18:29 +08:00

363 lines
9.5 KiB
Markdown

# 灾备计划 (Disaster Recovery Plan)
> **文档版本**: 1.0
> **最后更新**: 2026-06-17
> **审核周期**: 每季度审核一次
---
## 1. 概述
本文档定义了 Next_Edu 系统的灾备策略、恢复目标、备份方案和故障切换流程,确保在发生灾难性故障时能够快速恢复服务并最小化数据丢失。
### 1.1 适用范围
- 生产环境数据库(MySQL)
- 应用服务(Next.js)
- 备份文件(本地 + 异地)
- CI/CD 流水线
### 1.2 关键指标
| 指标 | 目标 | 说明 |
|------|------|------|
| **RTO** (Recovery Time Objective) | 4 小时 | 从故障发生到服务恢复的最长时间 |
| **RPO** (Recovery Point Objective) | 24 小时 | 最大可接受的数据丢失时间窗口 |
---
## 2. RTO/RPO 定义
### 2.1 RTO(恢复时间目标): 4 小时
**定义**: 从系统故障发生到服务完全恢复的最长允许时间。
**分解**:
| 阶段 | 预计耗时 | 说明 |
|------|---------|------|
| 故障检测 | 5 分钟 | 健康检查脚本自动检测 |
| 通知与决策 | 15 分钟 | 通知运维团队,决定是否切换 |
| 执行恢复 | 60 分钟 | 从备份恢复数据库 |
| 应用重启 | 10 分钟 | 重启应用并验证 |
| 数据验证 | 30 分钟 | 验证数据完整性 |
| 流量恢复 | 10 分钟 | 逐步恢复用户流量 |
| 缓冲时间 | 90 分钟 | 应对意外情况 |
| **总计** | **≤ 4 小时** | |
### 2.2 RPO(恢复点目标): 24 小时
**定义**: 最大可接受的数据丢失时间窗口。
**保障措施**:
- 每日凌晨 2 点全量备份(cron: `0 2 * * *`)
- 备份后自动校验完整性
- 备份后自动同步到异地存储
- 最坏情况下丢失不超过 24 小时数据
---
## 3. 备份策略
### 3.1 备份频率
| 备份类型 | 频率 | 时间 | 保留期 |
|---------|------|------|--------|
| 全量备份 | 每日 | 凌晨 2:00 (CST) | 本地 30 天,异地 90 天 |
| 异地同步 | 每日(备份后) | 凌晨 2:30 (CST) | 90 天 |
### 3.2 备份内容
- **数据库**: 使用 `mysqldump` 导出全部数据库,`gzip` 压缩
- **格式**: `db_backup_YYYYMMDD_HHMMSS.sql.gz`
- **存储位置**:
- 本地: `./backups/`
- 异地: S3/OSS/NFS(根据 `BACKUP_OFFSITE_BACKEND` 配置)
### 3.3 备份验证
每次备份后自动执行校验:
1. 文件存在性检查
2. 文件大小检查(最小 1KB)
3. gzip 完整性校验(`gunzip -t`)
4. SQL 内容结构检查(mysqldump 头部、语句数量)
5. SQL 语法校验(可选,需 `DATABASE_URL`)
### 3.4 备份保留策略
| 存储位置 | 保留期 | 清理方式 |
|---------|--------|---------|
| 本地 (`./backups/`) | 30 天 | `find -mtime +30 -delete` |
| 异地 (S3/OSS/NFS) | 90 天 | `backup-offsite-sync.sh` 自动清理 |
---
## 4. 故障切换流程
### 4.1 故障检测
1. **自动检测**: `health-check.sh` 定期运行,检查:
- 应用 HTTP 健康端点
- 数据库连接
- 磁盘空间
- 备份新鲜度
2. **手动报告**: 用户反馈、监控系统告警
### 4.2 故障切换步骤
```
┌─────────────────┐
│ 1. 检测故障 │ 健康检查失败 / 用户报告
└────────┬────────┘
┌─────────────────┐
│ 2. 通知运维 │ 电话/邮件/即时通讯通知运维团队
└────────┬────────┘
┌─────────────────┐
│ 3. 决策(5分钟) │ 评估故障严重程度,决定是否切换
└────────┬────────┘
┌────┴────┐
│ │
切换 不切换
│ │
▼ ▼
┌─────────┐ ┌─────────┐
│4. 执行 │ │ 修复主库 │
│ 切换 │ │ │
└────┬────┘ └─────────┘
┌─────────┐
│5. 验证 │ 健康检查、功能测试
│ 恢复 │
└────┬────┘
┌─────────┐
│6. 事后 │ 记录事件、复盘改进
│ 复盘 │
└─────────┘
```
### 4.3 执行故障切换
使用 `failover.sh` 脚本:
```bash
# 手动模式(交互式确认)
./scripts/failover.sh
# 半自动模式(检测到故障后自动切换,需确认)
./scripts/failover.sh --auto
# 演练模式(不实际执行)
./scripts/failover.sh --dry-run
# 指定备库
./scripts/failover.sh --standby "mysql://user:pass@standby-host:3306/dbname"
```
**前提条件**:
- 配置 `DATABASE_URL_STANDBY` 环境变量
- 备库已配置主从复制(如果是主从架构)
- 应用容器可通过 Docker 重启
---
## 5. 灾备演练
### 5.1 演练频率
| 演练类型 | 频率 | 触发方式 |
|---------|------|---------|
| 自动演练 | 每周一次 | CI 定时任务(每周一凌晨 4 点) |
| 手动演练 | 每月一次 | 运维人员手动触发 |
| 全量演练 | 每季度一次 | 完整故障切换演练 |
### 5.2 演练内容
1. **创建测试数据库** (`next_edu_dr_drill`)
2. **从最新备份恢复** 到测试数据库
3. **数据完整性检查**:
- 表数量对比(测试库 vs 源库)
- 记录数对比
4. **冒烟测试**:
- 基础表查询
- 关键业务表查询(users, schools)
5. **清理测试数据库**
6. **生成演练报告**
### 5.3 演练脚本
```bash
# Bash 版本(Linux/macOS)
./scripts/dr-drill.sh
# PowerShell 版本(Windows)
.\scripts\dr-drill.ps1
# 指定备份文件
./scripts/dr-drill.sh --backup backups/db_backup_20260617_020000.sql.gz
# 保留测试数据库(用于调试)
./scripts/dr-drill.sh --no-cleanup
```
### 5.4 演练报告
- **存储位置**: `docs/dr/reports/`
- **格式**: Markdown
- **内容**: 演练时间、步骤结果、RTO 评估、数据完整性指标
- **保留期**: 90 天(CI artifact)
---
## 6. 联系人列表
> **注意**: 以下为模板,请根据实际人员填写
### 6.1 主要联系人
| 角色 | 姓名 | 电话 | 邮箱 | 职责 |
|------|------|------|------|------|
| 主负责人 | [待填写] | [待填写] | [待填写] | 灾备决策、协调 |
| 备份负责人 | [待填写] | [待填写] | [待填写] | 备份执行、监控 |
| DBA | [待填写] | [待填写] | [待填写] | 数据库恢复 |
| 运维工程师 | [待填写] | [待填写] | [待填写] | 应用部署、网络 |
| 开发负责人 | [待填写] | [待填写] | [待填写] | 代码修复、功能验证 |
### 6.2 升级路径
1. **L1**: 运维工程师(5 分钟内响应)
2. **L2**: 主负责人 + DBA(15 分钟内响应)
3. **L3**: 全体联系人(30 分钟内响应)
---
## 7. 恢复步骤
### 7.1 从备份恢复数据库
```bash
# 1. 获取最新备份
LATEST_BACKUP=$(ls -t backups/db_backup_*.sql.gz | head -1)
echo "Using backup: $LATEST_BACKUP"
# 2. 校验备份完整性
./scripts/backup-verify.sh "$LATEST_BACKUP"
# 3. 恢复数据库
./scripts/restore-db.sh "$LATEST_BACKUP"
# 4. 验证恢复结果
mysql -u root -p -e "SELECT COUNT(*) FROM information_schema.tables WHERE table_schema='next_edu';"
```
### 7.2 完整恢复流程
1. **获取最新备份**
- 本地: `./backups/`
- 异地: 从 S3/OSS/NFS 下载
- CI artifact: 从 Gitea Actions 下载
2. **恢复数据库**
```bash
./scripts/restore-db.sh backups/db_backup_YYYYMMDD_HHMMSS.sql.gz
```
3. **重启应用**
```bash
docker restart nextjs-app
# 或
docker stop nextjs-app && docker rm nextjs-app
# 重新部署
```
4. **验证数据完整性**
```bash
# 运行健康检查
./scripts/health-check.sh
# 运行灾备演练(对比数据)
./scripts/dr-drill.sh --no-cleanup
```
5. **恢复流量**
- 验证应用功能正常
- 逐步恢复用户流量
- 监控系统指标
---
## 8. 监控与告警
### 8.1 健康检查
```bash
# 手动运行健康检查
./scripts/health-check.sh
# 输出 JSON 格式报告
./scripts/health-check.sh > health-report.json
```
**检查项**:
- 应用 HTTP 健康端点
- 数据库连接
- 磁盘空间(阈值 90%)
- 备份新鲜度(24 小时内)
### 8.2 告警条件
| 条件 | 严重级别 | 通知方式 |
|------|---------|---------|
| 应用不可达 | 严重 | 电话 + 邮件 |
| 数据库连接失败 | 严重 | 电话 + 邮件 |
| 磁盘空间 > 90% | 警告 | 邮件 |
| 备份超过 24 小时 | 警告 | 邮件 |
| 备份校验失败 | 严重 | 电话 + 邮件 |
| 灾备演练失败 | 警告 | 邮件 |
---
## 9. 环境变量配置
```bash
# 灾备配置
BACKUP_OFFSITE_BACKEND=none # s3|oss|nfs|none
BACKUP_OFFSITE_REMOTE= # 远程路径
BACKUP_OFFSITE_BUCKET= # 存储桶名
BACKUP_OFFSITE_ACCESS_KEY= # 访问密钥
BACKUP_OFFSITE_SECRET_KEY= # 秘密密钥
BACKUP_OFFSITE_REGION=us-east-1 # 区域
DR_DRILL_TEST_DB=next_edu_dr_drill # 演练测试数据库
HEALTH_CHECK_URL=http://localhost:8015 # 健康检查 URL
# 故障切换配置
DATABASE_URL_STANDBY= # 备库连接 URL
FAILOVER_APP_NAME=nextjs-app # 应用容器名
FAILOVER_APP_URL=http://localhost:8015 # 应用 URL
```
---
## 10. 文档维护
- **审核周期**: 每季度审核一次
- **更新触发**: 系统架构变更、联系人变更、演练发现问题
- **关联文档**:
- `docs/dr/dr-runbook.md` - 灾备操作手册
- `docs/dr/reports/` - 演练报告存档
- `scripts/` - 灾备相关脚本
---
## 11. 变更记录
| 日期 | 版本 | 变更内容 | 变更人 |
|------|------|---------|--------|
| 2026-06-17 | 1.0 | 初始版本 | - |