286 lines
7.8 KiB
Markdown
286 lines
7.8 KiB
Markdown
---
|
||
name: release-acceptance-checklist
|
||
description: 发布与验收检查清单——后端与全栈应用的 6 道关卡发布检查清单
|
||
metadata:
|
||
type: reference
|
||
---
|
||
|
||
# 发布与验收检查清单
|
||
|
||
适用于后端和全栈应用的 6 道关卡发布检查清单。防止出现「在我机器上能跑」和「我们忘了检查 X」之类的故障。
|
||
|
||
**铁律:未通过所有关卡,不得发布。**
|
||
|
||
---
|
||
|
||
## 发布关卡概览
|
||
|
||
```
|
||
功能完成
|
||
↓
|
||
关卡 1:功能验收 → 功能是否达到预期?
|
||
↓
|
||
关卡 2:非功能验收 → 是否快速、可靠、可观测?
|
||
↓
|
||
关卡 3:安全审查 → 是否安全?
|
||
↓
|
||
关卡 4:部署就绪 → 能否安全部署并回滚?
|
||
↓
|
||
关卡 5:发布执行 → 采用金丝雀部署 + 监控上线
|
||
↓
|
||
关卡 6:发布后验证 → 在生产环境是否真正生效?
|
||
```
|
||
|
||
---
|
||
|
||
## 关卡 1:功能验收
|
||
|
||
**问题:功能是否满足需求文档的要求?**
|
||
|
||
- [ ] 所有来自工单/PRD 的验收条件均有通过测试
|
||
- [ ] 正常路径端到端可用
|
||
- [ ] 边界情况已测试(空输入、最大长度、Unicode)
|
||
- [ ] 错误情况已测试(无效输入、未找到、超时)
|
||
- [ ] 数据完整性已验证(CRUD 周期产生正确状态)
|
||
- [ ] 向后兼容性已确认(现有客户端未被破坏)
|
||
- [ ] API 契约与 OpenAPI 规范一致
|
||
- [ ] 幂等性已验证(重试不会产生重复数据)
|
||
|
||
### 证据模板
|
||
|
||
| 需求 | 测试 | 状态 | 备注 |
|
||
|------|------|------|------|
|
||
| 用户可创建订单 | `orders.api.test:creates order` | ✅ 通过 | |
|
||
| 空购物车 → 报错 | `orders.api.test:rejects empty` | ✅ 通过 | |
|
||
| 支付失败已处理 | `payments.test:handles decline` | ✅ 通过 | |
|
||
|
||
---
|
||
|
||
## 关卡 2:非功能验收
|
||
|
||
**问题:是否快速、可靠、可观测?**
|
||
|
||
### 性能
|
||
|
||
- [ ] 响应时间在预算范围内(p95 < ___ms)——已实测,非假设
|
||
- [ ] 无 N+1 查询(通过查询日志检查)
|
||
- [ ] 新查询使用索引(`EXPLAIN ANALYZE`)
|
||
- [ ] 大数据集支持分页
|
||
- [ ] 缓存生效(命中率 > 80%)
|
||
- [ ] 连接池在负载下运行正常
|
||
|
||
### 可靠性
|
||
|
||
- [ ] 依赖失败时优雅降级(断路器)
|
||
- [ ] 瞬态故障的重试逻辑正常工作
|
||
- [ ] 所有外部调用均设置了超时
|
||
- [ ] 速率限制正确返回 429
|
||
- [ ] 健康检查端点已验证(`/health`、`/ready`)
|
||
|
||
### 可观测性
|
||
|
||
- [ ] 结构化日志包含请求 ID(非 `console.log`)
|
||
- [ ] 指标已暴露(请求数、延迟、错误率)
|
||
- [ ] 告警已配置(错误突增、延迟突增)
|
||
- [ ] 请求追踪端到端可用
|
||
- [ ] 新功能对应的仪表盘已更新
|
||
|
||
### 证据
|
||
|
||
| 指标 | 目标 | 实际值 | 状态 |
|
||
|------|------|--------|------|
|
||
| p95 响应时间 | < 500ms | ___ms | ✅/❌ |
|
||
| p99 响应时间 | < 1000ms | ___ms | ✅/❌ |
|
||
| 负载下错误率 | < 0.1% | ___% | ✅/❌ |
|
||
| 吞吐量 | > ___ RPS | ___ RPS | ✅/❌ |
|
||
|
||
---
|
||
|
||
## 关卡 3:安全审查
|
||
|
||
**问题:是否引入了安全漏洞?**
|
||
|
||
### 输入与输出
|
||
|
||
- [ ] 所有输入在服务端验证(永远不要信任客户端)
|
||
- [ ] 已防止 SQL 注入(仅使用参数化查询)
|
||
- [ ] 已防止 XSS(输出编码)
|
||
- [ ] 文件上传已验证(类型、大小、文件名已净化)
|
||
- [ ] 敏感端点已限流(登录、重置、API)
|
||
|
||
### 认证与数据
|
||
|
||
- [ ] 受保护端点需要有效凭据
|
||
- [ ] 用户只能访问自己的资源
|
||
- [ ] 管理后台路由需要管理员角色
|
||
- [ ] 令牌有过期机制(短生命周期访问令牌 + 刷新令牌)
|
||
- [ ] 密码已哈希(bcrypt/argon2,非 MD5/SHA)
|
||
- [ ] 敏感数据未记入日志(密码、令牌、PII)
|
||
- [ ] 密钥存储在环境变量中(非硬编码)
|
||
- [ ] 错误消息不泄露内部信息
|
||
|
||
### 依赖
|
||
|
||
- [ ] 无已知漏洞(`npm audit` / `pip audit` / `govulncheck`)
|
||
- [ ] 依赖版本已锁定在 lockfile 中
|
||
- [ ] 未使用的依赖已移除
|
||
|
||
---
|
||
|
||
## 关卡 4:部署就绪
|
||
|
||
**问题:能否安全部署,并在必要时回滚?**
|
||
|
||
### 代码
|
||
|
||
- [ ] 所有测试在 CI 中通过(而非「本地通过了」)
|
||
- [ ] 代码检查通过,构建成功
|
||
- [ ] 代码已审查并批准
|
||
- [ ] 无未解决的 TODO/FIXME/HACK
|
||
|
||
### 数据库
|
||
|
||
- [ ] 迁移在预发布环境使用类生产数据已测试
|
||
- [ ] 回滚迁移可正常工作(已测试!)
|
||
- [ ] 迁移不会造成破坏(仅新增)
|
||
- [ ] 已根据生产数据规模预估迁移耗时
|
||
- [ ] 数据回填方案已记录(如需)
|
||
|
||
### 配置
|
||
|
||
- [ ] 新增环境变量已在 `.env.example` 中记录
|
||
- [ ] 环境变量已在预发布环境设置并验证
|
||
- [ ] 环境变量已在生产环境设置
|
||
- [ ] 功能开关已配置(如适用)
|
||
|
||
### 回滚计划模板
|
||
|
||
```markdown
|
||
## 回滚计划:[功能]
|
||
|
||
### 触发回滚的条件
|
||
- 错误率 > 1% 持续 5 分钟
|
||
- p99 延迟 > 3000ms 持续 10 分钟
|
||
- 关键业务功能被破坏
|
||
|
||
### 步骤
|
||
1. 回退部署:[命令]
|
||
2. 回滚迁移(如已执行):[命令]
|
||
3. 清除缓存:[命令]
|
||
4. 通知团队:#incidents 频道
|
||
5. 验证回滚:[验证步骤]
|
||
|
||
### 预计耗时:[X 分钟]
|
||
### 数据恢复:[数据被修改时的恢复方案]
|
||
```
|
||
|
||
---
|
||
|
||
## 关卡 5:发布执行
|
||
|
||
### 部署顺序
|
||
|
||
```
|
||
1. 📢 在发布频道中公告
|
||
|
||
2. 🗄️ 数据库——执行迁移
|
||
- 运行迁移
|
||
- 验证完成
|
||
- 检查数据完整性
|
||
|
||
3. 🚀 部署——发布代码
|
||
- 先金丝雀发布(10% 流量)
|
||
- 监控 5 分钟
|
||
- 如正常 → 50% → 监控 → 100%
|
||
- 如不正常 → 立即停止
|
||
|
||
4. 🔍 冒烟测试
|
||
- 健康检查 → 200
|
||
- 登录正常
|
||
- 核心操作正常
|
||
- 无错误突增
|
||
|
||
5. ✅ 公告「发布完成。持续监控 30 分钟。」
|
||
```
|
||
|
||
### 金丝雀决策表
|
||
|
||
| 指标 | 基准值 | 金丝雀正常 | 停止 | 回滚 |
|
||
|------|--------|-----------|------|------|
|
||
| 错误率 | 0.05% | < 0.1% | 0.5% | > 1% |
|
||
| p95 延迟 | 300ms | < 500ms | 700ms | > 1000ms |
|
||
|
||
---
|
||
|
||
## 关卡 6:发布后验证
|
||
|
||
### 即时(0-30 分钟)
|
||
|
||
- [ ] 所有实例的健康检查均为绿色
|
||
- [ ] 错误率在正常范围内
|
||
- [ ] 延迟正常(p95、p99)
|
||
- [ ] 核心用户流程已手动测试
|
||
- [ ] 日志正常——无意外错误
|
||
- [ ] 告警保持静默
|
||
|
||
### 短期(1-24 小时)
|
||
|
||
- [ ] 无客户投诉
|
||
- [ ] 业务指标稳定(转化率、收入、注册数)
|
||
- [ ] 内存/CPU 稳定(无缓慢增长)
|
||
- [ ] 队列积压已清除
|
||
- [ ] 数据库性能稳定
|
||
|
||
### 发布后报告模板
|
||
|
||
```markdown
|
||
## 发布报告:[功能]
|
||
- 部署时间:[时间戳] 由 @[工程师]
|
||
- 耗时:[分钟]
|
||
|
||
| 检查项 | 状态 | 备注 |
|
||
|--------|------|------|
|
||
| 健康检查 | ✅ | 全部正常 |
|
||
| 错误率 | ✅ | 0.03%(基准值:0.05%) |
|
||
| p95 延迟 | ✅ | 310ms(基准值:300ms) |
|
||
| 核心流程 | ✅ | 订单创建已验证 |
|
||
|
||
发现的问题:无 / [详情]
|
||
是否回滚:否 / 是:[原因]
|
||
```
|
||
|
||
---
|
||
|
||
## 发布就绪评分
|
||
|
||
每道关卡评分 **0-2**:(0 = 未检查,1 = 部分检查,2 = 已全面验证并有证据)
|
||
|
||
| 关卡 | 评分 |
|
||
|------|------|
|
||
| 1. 功能验收 | /2 |
|
||
| 2. 非功能验收 | /2 |
|
||
| 3. 安全审查 | /2 |
|
||
| 4. 部署就绪 | /2 |
|
||
| 5. 发布执行计划 | /2 |
|
||
| 6. 发布后验证计划 | /2 |
|
||
| **总分** | **/12** |
|
||
|
||
**决策:**
|
||
- **12/12** → 上线 ✅
|
||
- **10-11** → 上线,附带已记录的例外事项 + 指定负责人
|
||
- **< 10** → 不得发布。先修复差距。
|
||
|
||
---
|
||
|
||
## 常见借口
|
||
|
||
| ❌ 借口 | ✅ 事实 |
|
||
|--------|--------|
|
||
| 「这只是一个小改动」 | 小改动每天都会导致故障 |
|
||
| 「我们在本地测过了」 | 本地 ≠ 生产环境 |
|
||
| 「出问题了再修」 | 你会在凌晨 3 点修。现在就预防。 |
|
||
| 「今天就是截止日期」 | 出错的代码比延期交付成本更高 |
|
||
| 「CI 通过了」 | CI 并不检查所有内容。执行检查清单。 |
|
||
| 「我们随时可以回滚」 | 只有当你有计划并测试过回滚才行 |
|
||
| 「上次这么干没问题」 | 幸存者偏差。每次都要走检查清单。 |
|