上线就绪清单
上线就绪清单用于在代码发布到生产环境之前,做最后的系统性检查。目标不是阻止发布,而是确保发布可控——出问题能及时发现、快速恢复。
要点
- 上线就绪清单在发布前做最后检查,确保发布可控
- 重点检查:测试覆盖、数据迁移、配置环境、监控告警、回滚方案
- 灰度发布:1% → 10% → 50% → 100%,每个阶段观察指标
- 回滚方案必须可行,能在 15 分钟内完成
1. 适用时机
- 新功能发布到生产环境
- 重大重构上线
- 数据迁移执行
- 基础设施变更(数据库、中间件、配置)
- 第三方服务切换
不需要上线就绪清单的场景:
- 小 bug 修复(有测试覆盖 + 回滚方案即可)
- 配置微调(有变更记录)
- 文档更新
2. 核心检查项
2.1 代码与测试
- 所有 PR 已合并并通过代码评审
- 自动化测试全通过(单元、集成、E2E)
- 手动测试覆盖关键路径(产品/QA 验收)
- 性能测试通过(压测报告在预期范围内)
- 安全扫描无高危漏洞
2.2 数据迁移
- 迁移脚本已 review,幂等可重复执行
- 大表迁移分批执行方案(避免锁表)
- 迁移数据量估算和耗时预估
- 回滚方案明确(失败后如何恢复)
- 数据校验步骤(迁移后对比源和目标)
Cloudflare D1 迁移示例
// wrangler.toml
[[migrations]]
tag = "v1"
new_classes = ["UserCounter"]
// 迁移脚本:migrations/001_add_user_table.sql
CREATE TABLE IF NOT EXISTS users (
id TEXT PRIMARY KEY,
name TEXT NOT NULL,
email TEXT NOT NULL UNIQUE,
created_at INTEGER NOT NULL
);
// 执行迁移
// wrangler d1 execute my-database --file=migrations/001_add_user_table.sql
// 验证迁移
// wrangler d1 execute my-database --command="SELECT COUNT(*) FROM users"2.3 配置与环境
- 生产环境配置准备(环境变量、密钥、Feature Flag)
- 数据库连接、缓存连接、第三方 API Key 配置正确
- 日志级别设置正确(生产不用 DEBUG)
- CDN / 缓存失效策略明确
- DNS / 负载均衡配置(如涉及)
wrangler.toml 配置示例
# wrangler.toml
name = "my-app"
main = "src/index.ts"
compatibility_date = "2026-06-21"
# 环境变量
[env.production]
vars = { ENVIRONMENT = "production", LOG_LEVEL = "info" }
# D1 数据库
[[env.production.d1_databases]]
binding = "DB"
database_name = "my-database"
database_id = "xxx-xxx-xxx"
# KV 命名空间
[[env.production.kv_namespaces]]
binding = "KV"
id = "xxx-xxx-xxx"
# R2 存储桶
[[env.production.r2_buckets]]
binding = "BUCKET"
bucket_name = "my-bucket"
# 密钥(通过 wrangler secret put 设置)
# wrangler secret put API_KEY
# wrangler secret put DATABASE_URL2.4 监控与告警
- 关键业务指标有监控(订单量、注册数、转化率)
- 系统指标有监控(错误率、延迟、CPU、内存)
- 告警规则配置(阈值、通知人、升级路径)
- Dashboard 准备好(发布后实时观察)
- 日志查询方式已知(出问题能立即查日志)
Hono 示例:健康检查端点
import { Hono } from 'hono'
const app = new Hono()
// 健康检查端点
app.get('/health', (c) => {
return c.json({
status: 'ok',
timestamp: new Date().toISOString(),
version: process.env.APP_VERSION || 'unknown'
})
})
// 深度健康检查:检查依赖服务
app.get('/health/ready', async (c) => {
const checks = {
database: false,
cache: false,
externalApi: false
}
try {
// 检查数据库
await c.env.DB.prepare('SELECT 1').first()
checks.database = true
} catch (error) {
console.error('Database check failed:', error)
}
try {
// 检查缓存
await c.env.KV.get('health:check')
checks.cache = true
} catch (error) {
console.error('Cache check failed:', error)
}
const allHealthy = Object.values(checks).every(v => v)
return c.json({
status: allHealthy ? 'ok' : 'degraded',
checks,
timestamp: new Date().toISOString()
}, allHealthy ? 200 : 503)
})2.5 回滚方案
- 回滚方式明确(代码回滚、Feature Flag、数据库回滚)
- 回滚步骤文档化,能在 15 分钟内完成
- 回滚后数据一致性确认(新旧数据结构兼容?)
- 回滚演练过(不是「理论上能回滚」)
- 回滚决策人明确(谁有权决定是否回滚)
回滚步骤示例
# 代码回滚
# 1. 找到上一个稳定版本
git log --oneline -10
# 2. 回滚到指定版本
git revert <commit-hash>
# 3. 部署
wrangler deploy
# Feature Flag 回滚(更快)
# 1. 关闭新功能
wrangler kv:key put --binding=FEATURE_FLAGS 'new-feature-enabled' 'false'
# 数据库回滚
# 1. 执行回滚迁移
wrangler d1 execute my-database --file=migrations/rollback_001.sql
# 2. 验证数据
wrangler d1 execute my-database --command="SELECT COUNT(*) FROM users"2.6 灰度策略
- 灰度比例确定(1% → 10% → 50% → 100%)
- 灰度观察指标明确(看什么指标判断是否正常)
- 灰度持续时间确定(每个阶段观察多久)
- 灰度扩大/回滚的触发条件(错误率 > 1% 就回滚)
- 灰度用户选择(内部用户、白名单用户、随机抽样)
Hono 示例:灰度发布
import { Hono } from 'hono'
const app = new Hono()
// 灰度中间件
app.use('*', async (c, next) => {
const userId = c.req.header('X-User-ID') || 'anonymous'
// 从 KV 读取灰度配置
const config = await c.env.KV.get('gray-release', 'json') || {
enabled: false,
percentage: 0,
whitelist: []
}
// 白名单用户
if (config.whitelist.includes(userId)) {
c.set('useNewFeature', true)
return next()
}
// 按比例灰度
const hash = userId.split('').reduce((acc, char) => acc + char.charCodeAt(0), 0) % 100
if (config.enabled && hash < config.percentage) {
c.set('useNewFeature', true)
return next()
}
c.set('useNewFeature', false)
return next()
})
app.get('/api/data', (c) => {
const useNewFeature = c.get('useNewFeature')
if (useNewFeature) {
// 新版本逻辑
return c.json({ version: 'v2', data: 'new' })
}
// 旧版本逻辑
return c.json({ version: 'v1', data: 'old' })
})2.7 沟通与协调
- 发布时间确定(避开高峰、节假日)
- 相关团队已通知(客服、运营、产品、依赖方)
- 用户公告准备(如有影响)
- 发布负责人明确(谁负责执行、谁负责观察、谁负责决策)
- 发布期间 on-call 人员安排
2.8 文档与记录
- 变更日志(changelog)已更新
- 用户文档已更新(如涉及功能变化)
- 运维文档已更新(如涉及部署变化)
- 发布记录模板准备(记录发布时间、版本、负责人、观察结果)
2.9 发布后验证
- 冒烟测试步骤准备(发布后立即执行的关键路径检查)
- 验证指标确定(看什么数据判断发布成功)
- 验证负责人明确
- 验证时间窗口确定(发布后 1 小时、24 小时、72 小时)
冒烟测试示例
#!/bin/bash
# smoke-test.sh
BASE_URL="https://api.example.com"
echo "Running smoke tests..."
# 1. 健康检查
curl -f "$BASE_URL/health" || exit 1
# 2. 核心接口
curl -f "$BASE_URL/api/v1/users" || exit 1
# 3. 写入测试
curl -f -X POST "$BASE_URL/api/v1/test" \
-H "Content-Type: application/json" \
-d '{"test": true}' || exit 1
echo "Smoke tests passed!"3. 发布流程模板
一个典型的发布流程:
T-1d:最终检查(代码冻结、配置确认、回滚方案确认)
T-2h:通知相关团队(即将发布)
T-0:执行发布(代码部署 + 数据迁移)
T+5min:冒烟测试(关键路径验证)
T+30min:灰度 1%(观察指标)
T+2h:灰度 10%(观察指标)
T+6h:灰度 50%(观察指标)
T+24h:全量 100%(持续观察)
T+72h:发布确认(指标正常,发布成功)
4. 评审会上容易漏的点
- 回滚方案:问「发布后发现问题,怎么回滚?需要多久?」
- 数据迁移:问「数据迁移需要多久?会影响在线服务吗?」
- 监控告警:问「怎么知道发布成功了?看什么指标?」
- 沟通:问「客服知道这次发布吗?用户会看到什么变化?」
- 决策权:问「出问题了谁决定回滚?」
5. 通过标准
- 所有阻塞项(blocking)已解决
- 回滚方案可行,演练过
- 监控告警到位
- 灰度策略明确
- 沟通已到位
- 发布负责人确认
6. 不发布的情况
以下情况应该推迟发布:
- 关键测试失败
- 回滚方案没想清楚
- 监控告警没配
- 相关团队没通知
- 发布负责人不在
- 临近节假日或业务高峰
7. 维护建议
上线就绪清单需要随团队实践更新:
- 发布流程变化时(如从手动切到自动),调整相关检查项
- 出现发布相关的事故后,把根因对应的检查项加进来
- 团队规模扩大时,强化沟通和协调要求
- 每半年复审一次,删除过时的检查项