feat(p6): production hardening with circuit breaker, backup, monitoring and chaos engineering
P6 生产硬化阶段交付物(46 文件):
## 1. API Gateway 中间件链(services/api-gateway/internal/middleware/)
- circuit-breaker.go: gobreaker v2 熔断器(5s 窗口/50% 错误率/30s OPEN→HALF_OPEN)
- ratelimit.go: 令牌桶限流(sync.Map + cleanup goroutine,默认 100rps/20 burst)
- cors.go: CORS 中间件(CORS_ORIGINS 环境变量)
- recovery.go: panic 恢复 + uuid request_id
- security.go: 安全头 + 请求体 10MB 限制
- requestid.go: 请求 ID 注入
- health/health.go: /healthz + /readyz 健康检查
- main.go: 重写注册全部中间件链(Recovery→RequestID→CORS→Security→BodyLimit→RateLimit→CircuitBreaker→Auth)
## 2. 基础设施硬化(infra/)
- backup/backup-mysql.sh: MySQL 全量备份(mysqldump+gzip,按服务独立)
- backup/restore-mysql.sh: 恢复脚本
- backup/backup-cron.sh: cron 调度入口(5 服务批量备份)
- alertmanager/alertmanager.yml: 告警路由(webhook + 邮件示例)
- prometheus/rules.yml: 8 条告警规则(服务可用性/性能/资源 3 组)
- grafana/dashboards/microservices-overview.json: 4 panel 仪表盘
- grafana/provisioning/: 数据源和仪表盘 provisioning
- k8s/namespace.yaml: 4 命名空间(edu-system/services/monitoring/ingress)
- k8s/api-gateway-deployment.yaml: Deployment + Service 骨架
- chaos/experiments.yaml: 3 个 Litmus 混沌实验(pod-kill/network-latency/disk-fill)
- docker-compose.monitoring.yml: 监控栈 profile
- security/secrets.example.env: 8 项密钥占位符
- security/waf-rules.conf: ModSecurity WAF 规则骨架
## 3. 业务服务健康检查 + 优雅停机(5 个 NestJS 服务)
- services/{iam,core-edu,content,msg,classes}/src/shared/health/: /healthz + /readyz
- services/{iam,core-edu,content,msg,classes}/src/shared/lifecycle/: OnModuleInit + OnApplicationShutdown
## 4. Python 服务健康检查
- services/{ai,data-ana}/src/health/health.py: FastAPI APIRouter
## 5. 运维文档
- docs/architecture/runbooks/p6-hardening.md: P6 总览 Runbook(9 章节)
- docs/architecture/runbooks/incident-response.md: 事件响应手册(5 章节)
- docs/architecture/004-p6-addendum.md: 004 架构补记 P6 章节
- docs/troubleshooting/known-issues-p6-addendum.md: 15 条 P6 场景→技术映射
## 验收信号
- RPO ≤ 15min(MySQL 备份 + binlog PITR)
- RTO ≤ 30min(K8s 滚动更新 + DNS 切换)
- P99 ≤ 500ms(熔断 + 限流 + 缓存)
- 熔断器错误率 > 50% 触发 OPEN
- 限流 100rps/20 burst
- 备份保留 7 天
- 混沌实验每月 1 次
This commit is contained in:
171
docs/architecture/runbooks/incident-response.md
Normal file
171
docs/architecture/runbooks/incident-response.md
Normal file
@@ -0,0 +1,171 @@
|
||||
# 事件响应手册
|
||||
|
||||
> 目标:规范生产事件的分级、响应、处置与复盘,确保 RTO ≤ 30min
|
||||
> 关联:`docs/architecture/runbooks/p6-hardening.md`
|
||||
|
||||
## 1. 事件分级
|
||||
|
||||
| 级别 | 定义 | 影响 | 响应时效 | 升级 |
|
||||
|------|------|------|----------|------|
|
||||
| P0 | 全站不可用 / 核心数据损坏 | 全部用户 | 5 分钟内响应 | 立即升级至 CTO |
|
||||
| P1 | 核心功能不可用 / 关键 SLO 破坏 | 大量用户 | 10 分钟内响应 | 升级至服务负责人 |
|
||||
| P2 | 部分功能降级 / 非核心故障 | 部分用户 | 30 分钟内响应 | 服务负责人跟进 |
|
||||
| P3 | 单点告警 / 潜在风险 | 少量/无用户 | 工作时间内响应 | On-Call 自行处理 |
|
||||
|
||||
### 1.1 分级示例
|
||||
|
||||
- P0:网关全挂、主 DB 不可用且无法故障转移、数据丢失超过 RPO
|
||||
- P1:登录不可用、课程播放不可用、Kafka 生产阻塞
|
||||
- P2:消息推送延迟、报表生成失败、单个非核心服务宕机
|
||||
- P3:单 Pod 重启、磁盘使用率告警、慢查询告警
|
||||
|
||||
## 2. 响应流程
|
||||
|
||||
```
|
||||
发现 → 确认 → 升级 → 处理 → 恢复 → 复盘
|
||||
```
|
||||
|
||||
### 2.1 发现
|
||||
|
||||
- 告警来源:Prometheus / Alertmanager / 用户反馈 / 人工巡检
|
||||
- 第一动作:在 On-Call 群贴告警,标注收到时间
|
||||
|
||||
### 2.2 确认
|
||||
|
||||
- On-Call 5 分钟内确认告警真实性
|
||||
- 排除误报(探针抖动、已知维护窗口)
|
||||
- 初步定级,创建事故工单(Jira / 飞书项目)
|
||||
|
||||
### 2.3 升级
|
||||
|
||||
- 超出处置能力 → 立即升级
|
||||
- P0/P1 → 拉事故群,通知相关服务 Owner
|
||||
- 涉及外部公告 → 通知客服与公关
|
||||
|
||||
### 2.4 处理
|
||||
|
||||
- 遵循"先恢复,后定位"原则
|
||||
- 优先使用预案:回滚、扩容、降级、熔断、切换
|
||||
- 每个操作记录时间戳与执行人
|
||||
- 关键决策需事故指挥确认
|
||||
|
||||
### 2.5 恢复
|
||||
|
||||
- 健康检查通过、SLO 恢复
|
||||
- 观察 15 分钟确认稳定
|
||||
- 关闭事故工单,进入复盘
|
||||
|
||||
### 2.6 复盘
|
||||
|
||||
- 48 小时内提交复盘报告
|
||||
- 无 blame 文化:对事不对人
|
||||
- 输出改进项,录入 `docs/architecture/roadmap/tech-debt.md`
|
||||
|
||||
## 3. On-Call 轮值
|
||||
|
||||
### 3.1 轮值制度
|
||||
|
||||
- 主备双人轮值,每周轮换
|
||||
- 工作日:9:00-21:00 主,其余备
|
||||
- 节假日:全天主备
|
||||
- 交接:周一 10:00 站会交接,遗留问题清单
|
||||
|
||||
### 3.2 联络方式
|
||||
|
||||
- 电话:主 + 备 + 升级链
|
||||
- 即时通讯:飞书 On-Call 群
|
||||
- 告警:PagerDuty / 飞书机器人
|
||||
|
||||
### 3.3 响应要求
|
||||
|
||||
- P0/P1:电话 5 分钟内接听
|
||||
- 告警确认:群内 5 分钟内回复
|
||||
- 无法响应:自动升级至备值
|
||||
|
||||
## 4. 沟通模板
|
||||
|
||||
### 4.1 事故通报(初报)
|
||||
|
||||
```
|
||||
【事故通报】<P级别> - <简述>
|
||||
时间:<YYYY-MM-DD HH:MM>
|
||||
级别:<P0/P1/P2/P3>
|
||||
影响:<受影响功能/用户范围>
|
||||
现状:<已知信息>
|
||||
负责人:<On-Call>
|
||||
下一步:<计划动作>
|
||||
```
|
||||
|
||||
### 4.2 进展更新(每 30 分钟或重大变化)
|
||||
|
||||
```
|
||||
【进展更新】<事故标题>
|
||||
时间:<HH:MM>
|
||||
进展:<自上次以来发生/完成的事>
|
||||
当前状态:<仍受影响的功能>
|
||||
下一步:<接下来 30 分钟计划>
|
||||
```
|
||||
|
||||
### 4.3 恢复通知
|
||||
|
||||
```
|
||||
【恢复通知】<事故标题>
|
||||
恢复时间:<HH:MM>
|
||||
持续时长:<时长>
|
||||
原因:<根因摘要>
|
||||
影响:<最终影响评估>
|
||||
后续:<复盘会时间>
|
||||
```
|
||||
|
||||
### 4.4 复盘报告
|
||||
|
||||
```
|
||||
【复盘报告】<事故标题>
|
||||
时间:<起止时间>
|
||||
级别:<P级别>
|
||||
影响:<用户/功能/数据>
|
||||
时间线:<关键事件时间轴>
|
||||
根因:<5why 分析>
|
||||
处置:<做了什么、有效/无效>
|
||||
改进项:<TODO + 负责人 + 截止>
|
||||
经验:<可沉淀到 known-issues / runbook 的内容>
|
||||
```
|
||||
|
||||
## 5. 常见事故处置
|
||||
|
||||
### 5.1 DB 主从切换
|
||||
|
||||
1. 确认主库故障(健康检查、连接超时)
|
||||
2. 触发自动故障转移(Patroni / Orchestrator)
|
||||
3. 若自动失败,手动 `./scripts/db/failover.sh --service <svc>`
|
||||
4. 更新连接配置 / 刷新连接池
|
||||
5. 验证读写正常、数据位点
|
||||
6. 旧主恢复后作为从库加入
|
||||
|
||||
### 5.2 Kafka 消费堆积
|
||||
|
||||
1. 查看堆积:`kubectl exec -- kafka-consumer-lag`
|
||||
2. 定位慢消费者:查日志、trace
|
||||
3. 扩容消费者副本(HPA 或手动)
|
||||
4. 若处理逻辑慢:临时降级非核心处理
|
||||
5. 堆积消化后恢复
|
||||
6. 复盘:扩容阈值、消费者并发配置
|
||||
|
||||
### 5.3 服务雪崩
|
||||
|
||||
1. 确认雪崩源头(哪个下游故障)
|
||||
2. 确认熔断器已打开(Gateway 状态)
|
||||
3. 若未打开:手动 `./scripts/gateway/circuit-breaker.sh open <service>`
|
||||
4. 降级非核心功能
|
||||
5. 扩容上游服务应对重试流量
|
||||
6. 修复下游、半开试探、逐步恢复
|
||||
7. 复盘:熔断参数、依赖隔离
|
||||
|
||||
## 附录:升级链
|
||||
|
||||
| 级别 | 第一响应 | 升级 1 | 升级 2 | 升级 3 |
|
||||
|------|----------|--------|--------|--------|
|
||||
| P0 | On-Call | 服务负责人 | 架构负责人 | CTO |
|
||||
| P1 | On-Call | 服务负责人 | 架构负责人 | - |
|
||||
| P2 | On-Call | 服务负责人 | - | - |
|
||||
| P3 | On-Call | - | - | - |
|
||||
Reference in New Issue
Block a user