CHARLIE SAYS

查理如是说
DATE 2026-08-24
THEME
SERIES / JHIPSTER / P-245 · JHipster 项目开发

JHipster 开发 28:生产上线 Checklist

第 18、19 篇搭好了 CI/CD 与 K8s 底座,这一篇是走到最后一步:按什么清单放行一个版本进生产。这份 checklist 来自我们四次大版本上线(含一次微服务拆分上线)的复盘沉淀,每次上线周会用它逐项打勾——没打完勾不发版。表格可直接抄走改造。

为什么需要 Checklist

上线事故的共性不是”技术难题”,而是”忘了”。第 29 篇会展开我们那次默认账号没禁用被扫描器盯上的事故——每一项 checklist 背后最好都站着一个真实教训。Checklist 的价值在于把记忆外化:凌晨两点发版的人不需要想起所有事,只需要照单执行。

一、安全

#检查项标准/做法相关篇目
S1JWT secret 强度与来源86+ 位随机 Base64,K8s Secret 注入,禁止入库第 21 篇
S2默认账号处置admin 改强密 + 禁用 user 演示账号,或首启强制改密
S3HTTPS 全链TLS 终止在网关/Ingress,内部流量按需 mTLS第 19 篇
S4依赖 CVE 扫描dependency-check / Snyk 在 CI 阻断 High 以上第 18 篇
S5Swagger/管理端点收敛prod 关 Swagger;actuator 走独立管理端口 + NetworkPolicy第 20 篇
S6CORS 与 CSP白名单域名;安全响应头过 securityheaders.com 检查
S7数据库账号最小权限应用账号无 DDL 权限(Liquibase 用独立迁移账号)第 7 篇
S8敏感信息泄漏复查git 历史扫 secret;日志不打印令牌与密码第 21 篇

二、数据库

#检查项标准/做法
D1Liquibase 空库演练镜像里跑 liquibase update,从零建库成功
D2生产副本演练用生产量级快照跑全部 changeSet,记录耗时
D3大表变更锁评估加索引用 CREATE INDEX CONCURRENTLY;改列类型评估锁与重写
D4前滚兼容设计见下文”回滚预案”小节,双写/过渡期列
D5备份恢复演练恢复一次备份到隔离环境并抽样验证,而不是只看备份”成功”日志
D6连接池与超时池参数 = 压测值;statement timeout 开启防慢查询拖死连接
D7迁移账号分离应用账号与 Liquibase 账号分权,迁移窗口外不可 DDL

三、性能

#检查项标准/做法
P1压测基线staging 以 1.5 倍峰值流量压过,P99 达 SLA
P2慢 SQL 清零慢日志阈值内无未评估条目
P3缓存预热与命中率热点数据预热脚本;hit ratio 看板就位
P4JVM 与容器对齐MaxRAMPercentage=70;limit 与请求值合理差
P5前端首屏指标LCP/打包体积对比上一版无劣化
P6压测后资源回落压测完池/CPU/GC 指标回落,无慢泄漏迹象

四、可观测

#检查项标准/做法
O1日志聚合JSON 格式落 Loki/ELK,traceId 贯穿
O2指标与看板Micrometer → Prometheus,RED 看板每服务一张
O3告警规则错误率、P99、池占用、Pod 重启四条最低配,值班路由确认
O4链路追踪采样率设定并验证跨服务串联
O5日志级别预案运行时动态调级的方法演练过(actuator loggers)
O6业务指标订单量/支付成功率等业务大盘,故障时判断影响面的第一入口

五、K8s

#检查项标准/做法
K1镜像 taglatest,用 git SHA/版本号,可追溯可回滚
K2探针readiness 指向真实依赖就绪(含 Liquibase 完成);liveness 不查外部依赖防误杀
K3资源限制requests/limits 显式设置,与 JVM 对齐
K4HPA指标选 CPU 或自定义 QPS;min/max 与压测结论一致
K5PDBminAvailable 保证滚动更新与节点维护时容量
K6优雅停机server.shutdown: graceful + preStop sleep,配合 terminationGracePeriod
K7Ingress/TLS 证书证书有效期监控,自动续期验证
K8Config/Secret 与版本配置变更走 GitOps PR,与镜像版本对应

六、回滚预案

上线方案的另一半是”怎么退回来”。两条腿:

镜像回滚(分钟级):

kubectl rollout undo deployment/order-service
# 或显式回退到版本 tag
kubectl set image deployment/order-service order=registry.mycompany.com/order-service:v2.3.1

前提是 K1 的版本化 tag 与流控放行。

Liquibase 前滚兼容(真正的难点):镜像回退了,数据库却回不去——新版本可能已执行 changeSet。所以数据库变更必须设计成”前滚兼容”:老代码在新 schema 上仍能正确运行。约定三则:

变更类型前滚兼容做法回滚时表现
加列加 nullable 列,老代码忽略之无影响
删列/改类型分两个版本:先停用(代码不再读写),下个版本再删删除动作发生在确认稳定后
改约束/重命名双写过渡:新旧并存一个发布周期老代码走旧列

核心思想:每一个发布版本,数据库 schema 只做”加法”或”无破坏”的变更,破坏性变更永远延后一个版本。这让”回滚镜像”成为永远安全的操作。执行顺序也有讲究:Liquibase 在 K8s 里作为 init container 或 Job 先跑(第 19 篇的部署结构),新 Pod readiness 通过后再接流量。

另准备一份”回滚决策单”:谁有权拍板回滚(值班 leader)、多长时间内异常自动触发讨论(错误率 > 2% 持续 5 分钟)、回滚后的数据补账流程(写了新 schema 字段的数据怎么处理)。上线前预演一次回滚,我们第一次预演就发现 preStop 缺失导致滚动更新丢请求,这种问题不能在生产首演。

Checklist 的工程化落地

清单贴在 wiki 上会死,工程化才能活。我们的三个做法:

第一,checklist 进 issue 模板。 发布单本身就是模板,六块清单作为 checkbox 出现,放行 = 所有框打完:

<!-- .github/ISSUE_TEMPLATE/release.md -->
## 发布单:vX.Y.Z
- [ ] S1 JWT secret 来源与强度复核
- [ ] S2 默认账号处置(改密/禁用)
- [ ] D1 Liquibase 空库演练通过
- [ ] D2 生产量级副本演练,耗时记录:___
- [ ] P1 staging 压测 1.5x 峰值,P99:___
- [ ] O3 告警规则验证(人为触发一条)
- [ ] K2 探针检查(liveness 无外部依赖)
- [ ] R  回滚预演完成,决策单签署:___

留空填数字的项(P99、耗时)逼着执行者真跑一遍,而不是凭记忆打勾。

第二,能自动化的项移进 CI。 人会忘,pipeline 不会。逐项搬运的进度:S4(CVE 扫描)、S8(secret 扫描)、K1(latest tag 检测)已完全自动化;D1(空库演练)在 CI 里起一个干净 Postgres 容器跑 liquibase update 已实现一半。原则:每季度把手工打勾最多的三项评估自动化,让人的注意力留给判断性检查。

第三,清单有 owner 和复盘回路。 每块清单指定责任人(安全块归安全接口人、K8s 块归平台组),上线次日复盘的固定议程是”本次哪些项执行有问题、哪些项该改写”。第 29 篇的事故如何长出新行:坑 5 锁表之后,D3 从”评估锁风险”改写成了明确指令”大表索引必须 CONCURRENTLY + runInTransaction=false”,三个月后同款变更在演练中就被拦下了。

上线日流程(浓缩版)

T-1d  checklist 全项打勾;生产副本 Liquibase 演练完成;告警值班确认
T-0   金丝雀:先放 1 个 Pod(或 5% 流量)观察 30 分钟看板
T+30m 全量滚动更新;盯错误率/P99/池占用/订单大盘
T+2h  留观,每 30 分钟记录一次关键指标
T+1d  复盘会:本次 checklist 漏项进清单

上线当天的 pre-flight 快速核对(五分钟版,完整清单的抽样):

# 镜像与版本确认:tag 是版本号而非 latest
kubectl -n prod get deployment -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.spec.template.spec.containers[0].image}{"\n"}{end}'
# 探针与资源确认
kubectl -n prod get deploy order-service -o yaml | grep -A3 -E 'livenessProbe|readinessProbe|resources:'
# 告警通道演练:人为触发一条测试告警,值班手机能收到
# 回滚演练:在 staging 执行一次 rollout undo,记录耗时(应 < 3 分钟)

小结

  • 清单的价值是把”忘了”变成”照单执行”:安全、数据库、性能、可观测、K8s、回滚六大块逐项打勾再放行。
  • 数据库是回滚的根:前滚兼容(加法式变更、破坏延后一版)让镜像回滚永远安全。
  • 探针、优雅停机、版本化 tag 这三个 K8s 细节决定滚动更新与回滚的成色。
  • 上线走金丝雀,指标盯四件套,次日复盘反哺清单——checklist 是活的资产。

系列导航

← Angular 22+ 教程 28:NgModule 到 Standalone 的演进 目录 算法 029:算法思想:二分法 →
← 返回文章列表