第17章 上线与迁移:把可重建能力变成交付流程
上线不是把 Compose 搬到生产
教学环境使用固定本地密码、单节点 broker 和明文内网连接,目的是减少理解成本。生产需要依据实际组织边界配置身份、加密、网络限制和秘密管理,还要规划高可用与备份。这里讨论上线设计,不声称随书实验已经验证这些生产设施。复制一份配置文件无法替代容量、权限和故障演练。
接入源库之前先检查 ROW 日志、行镜像、复制身份、日志保留和快照权限。对已有数据库修改配置可能影响其他复制任务,应由数据库维护流程评估。连接器 server id、topic 前缀、内部 topic 和消费组必须有命名与所有权约定,避免不同应用在同一个集群中发生冲突。
把输入、转换和读取分开发布
连接器版本、消费者转换版本与查询功能版本可以分别变化。若把它们锁成一个不可观察的大开关,出现错误时很难判断来源。更稳妥的方式是先让读取端兼容新文档,再部署新转换,验证数据准备,最后启用业务功能。每个版本都应记录使用的输入契约和支持的 schema 范围。
对于不兼容转换,优先建立新世代而不是原地覆盖全部在线对象。新世代可以接受完整对账和业务查询验收,旧世代仍可保留以便回退。当前实验已经验证隔离重建和内容相等,但没有提供生产查询指针服务,因此真正上线时需要实现并测试切换原子性。
位点操作需要成为受控动作
消费组 reset、连接器重置与内部 topic 清理都会改变恢复依据。它们不应隐藏在“重新部署”脚本里。执行前保存原位置、目标位置、原因、预计影响和回退方案,执行后通过业务探针与对账确认。特别是向前跳过位置,可能造成永久缺失,不能仅以 lag 变小作为成功标准。
本书用 –replay 从起点消费属于受控实验,且同组历史完整保留。生产回放应使用专门恢复流程,避免与正常组成员并发竞争。新世代通常使用新消费组更清楚,也能让绑定关系拒绝错误复用。所谓“复用方便”如果让输入身份失去含义,后续恢复成本会更高。
交付物必须能对应同一个源码
仓库保存书稿、实验源码、依赖和构建脚本。流水线从同一提交运行真实实验,生成 EPUB 和分章网页,验证内容一致、下载 ZIP 和移动端,再部署 Pages。Release 使用这次成功 CI 已经生成的下载产物,不能在本地重建另一份同名 EPUB 后上传,否则版本号相同也可能字节不同。
我们记录 EPUB 字节数与 SHA256,并比较 CI artifact、Pages 公共下载和 Release 公共资产。EPUBCheck 对同一产物执行验证。源码提交说明实验由什么代码生成,运行证据说明发生了什么,字节摘要说明读者拿到什么。三者彼此关联,才能避免“源码正确但下载仍旧版”的常见交付问题。
文档更新与产品构建分开
交付说明和 canonical 证据回写使用跳过 CI 的文档提交,工作流也按产品输入路径过滤。否则单纯更新发布日期可能触发重建,造成 Pages 上的 EPUB 与已有 Release 不同。产品输入发生变化则应重新验证,并按版本规则发布新补丁,保留旧资产,不覆盖同一已发布版本。
随书 ZIP 排除 evidence 运行目录和缓存,防止旧的 kill 标记或临时日志进入下一次复现。证据通过独立报告和 artifact 分发,实验包只包含重现所需源码、SQL、Compose、依赖和说明。独立解压后完整重跑,比仅检查文件存在更能发现路径和依赖遗漏。
上线验收要面向业务
技术验收包括真实链路、重复恢复、删除、schema 和重建;业务验收还包括筛选结果、排序、可见性、字段单位与异常提示。PostgreSQL 文档相等不能证明某个前端展示没有把分当元,也不能证明权限过滤正确。本书的在线阅读界面验收与数据投影验收属于不同对象,不能互相充当证据。
生产发布后保留观察窗口,检查错误率、延迟、源库负载和对账差异,再回收旧资源。若发现问题,优先暂停新功能或回到已验证世代,同时保留输入日志和现场。不要为了让发布单快速关闭而删除全部旧状态。
本章练习
写一份新字段上线的发布单,包含输入配置、转换版本、历史迁移、查询兼容、对账和回退。再说明为什么一个仅修改 DELIVERY 的提交不应该自动生成新 EPUB。