Kvmzen 博客
← 返回技术实践

OpenShip 回滚:生产验收清单

CI/CD 实践 ·约 11 分钟阅读

OpenShip 回滚:生产验收清单

官方安装文档给出的自托管最低要求是 2 核 CPU、2 GB RAM 和 20 GB 磁盘。这说明 OpenShip 回滚首先依赖可重复启动的运行环境,但它不能替你恢复业务数据。(openship.io)

最危险的失败案例是:平台显示回滚成功,但旧代码无法读取新数据库。因此,OpenShip 回滚不能只看控制台按钮;上线前必须同时验证旧产物可启动、旧配置可恢复、数据库变更向后兼容、流量切换完成,并确认后台任务没有重复执行。遇到破坏性数据库迁移时,应用回滚和数据恢复必须分开设计。

这篇文章适合准备把 OpenShip 用于正式生产发布的 AI SaaS 团队、需要建立发布审批证据的运维人员,以及运行数据库、Worker 或长连接 Agent 服务的开发者。

OpenShip 回滚的三层成功标准

你可以先把“回滚成功”拆成 3 个层级,避免团队在同一个词上产生误判。

层级 测试对象 必须保存的证据 通过标准 失败动作
控制台成功 回滚操作、目标版本、部署状态 部署 ID、目标版本、操作日志 目标版本明确,操作记录完整 暂停发布审批,确认实际运行版本
容器成功启动 旧镜像、启动命令、依赖和端口 容器日志、版本标识、实例启动记录 新实例能独立启动,不依赖残留容器 重新构建或补齐旧版本产物
业务请求恢复 普通 HTTP、流式响应、WebSocket、关键 API 请求 ID、响应结果、错误日志 关键路径恢复,降级范围符合项目要求 停止流量切换,保留现场并执行补偿

OpenShip 官方页面描述了不可变部署快照、旧版本保留、健康检查、流量切换和一键回滚。这些属于平台功能声明,不等于你的数据库、密钥、队列和外部服务也会自动回到旧状态。(openship.io)

你需要在发布记录中提前写清:

  • 哪些接口属于关键接口;
  • 哪些功能允许暂时降级;
  • 哪些数据必须保持完整;
  • 谁可以触发回滚;
  • 谁负责数据库恢复;
  • 什么证据出现后才算业务恢复。

不要直接套用“零中断”作为结论。官方页面确实描述了滚动发布、连接排空和零停机能力,但你的应用是否真的没有请求错误,仍要以实际请求日志和长连接测试为准。(openship.io)

产物与运行依赖

OpenShip 的生产部署流程会把构建结果标记为不可变、带版本的产物,并将新实例启动在隔离网络中;旧版本保留后才具备回滚基础。(openship.io)

验收时不要只确认“历史版本还在列表里”,而要完成以下测试:

  1. 记录目标版本的提交标识、镜像摘要或部署 ID。
  2. 确认对应镜像仍然可以取得,不能依赖本地缓存。
  3. 核对旧版本的启动命令、端口、依赖文件和运行时版本。
  4. 删除或停止当前旧容器,再启动一个全新实例。
  5. 从新实例日志确认应用读取的是目标版本,而不是当前代码。
  6. 保存部署日志、启动日志和健康检查结果。

OpenShip 的官方快速开始文档说明,项目可以通过 openship init 初始化,再使用 openship deploy 完成部署。(openship.io) 但生产回滚验收不能只重复部署命令,还要模拟“旧产物重新启动”的场景。否则,残留容器、缓存镜像或旧挂载目录都可能掩盖真实问题。

通过: 新实例在没有旧容器帮助的情况下启动,并能返回版本标识。
不通过: 只能在原容器中恢复,或镜像、依赖和启动命令无法重新取得。

配置与密钥一致性

OpenShip 文档覆盖环境变量配置,官方页面也描述了按环境管理的密钥能力。(openship.io) 但“回滚应用”与“回滚配置”是两个验收对象。旧代码启动后,实际读取的环境变量可能仍是新版本配置。

重点检查 4 类内容:

  • 数据库地址: 是否仍指向新建实例、临时库或错误区域;
  • 外部 API 地址: 是否从测试端点切回生产端点,或反过来;
  • 密钥权限: 旧版本是否仍拥有所需的读取、写入和队列权限;
  • 功能开关: 新版本新增的开关是否会让旧代码进入未知分支。

可以在部署记录中保存配置清单,但敏感值只能记录哈希、版本号或更新时间。例如,记录 PAYMENT_API_KEY:hash-xxx,rotated_at:某时间,不要把真实密钥写入日志、截图或文章示例。

配置类别 回滚时要验证什么 证据位置 失败处理
环境变量 实际注入版本与预期一致 容器启动摘要、配置哈希 恢复旧配置版本后重新启动
密钥 旧代码所需权限仍有效 密钥版本、权限审计记录 禁止复制明文,重新授权或轮换
外部服务 地址、区域和协议没有错配 应用配置摘要、请求日志 暂停流量,切回兼容端点
功能开关 旧代码能识别当前开关 配置版本记录、关键接口测试 关闭新开关或禁止回滚

数据库迁移边界

数据库迁移是 OpenShip 回滚中最容易被误判的部分。平台可以回到旧应用产物,但这不等于数据库会自动回到旧 Schema,也不等于持久化数据会自动恢复。

你应把迁移分成 3 类:

  • 向后兼容迁移: 先增加字段或索引,旧代码仍能读取原有结构;
  • 可逆迁移: 有明确的反向脚本,并已在隔离数据上验证;
  • 破坏性迁移: 删除字段、改变字段类型、改变约束或重写数据,旧代码可能无法读取。

采用向后兼容方式时,推荐顺序是:

  1. 先发布能同时理解新旧字段的代码;
  2. 再执行数据库迁移;
  3. 观察旧代码读取新 Schema 的结果;
  4. 确认没有破坏性写入后,才允许回滚应用;
  5. 最后再清理旧字段或旧逻辑。

如果数据库已经发生破坏性迁移,不要把“OpenShip 回滚应用”写成“数据库自动恢复”。你需要单独提供备份、时间点恢复或独立副本的证据,并验证恢复后的数据是否能被目标版本读取。OpenShip 官方页面描述了数据库服务与备份能力,但备份存在不代表你的项目已经完成恢复演练。(openship.io)

关于数据库备份策略,可以进一步参考 数据库备份与恢复方案,把备份保留、恢复负责人和恢复后校验写进发布记录。

健康检查与流量切换

健康检查只能说明实例满足某些就绪条件,不一定说明关键业务已经恢复。你至少要分别测试:

  • 普通 HTTP 请求;
  • AI 流式响应;
  • WebSocket 或其他长连接;
  • 鉴权、计费、任务提交等关键接口;
  • 外部 API 调用和错误重试。

OpenShip 官方页面列出了健康检查、加权路由、粘性会话和 WebSocket 支持;源代码仓库中的路由设计文档还强调,路由配置应绑定到具体部署,并在回滚时恢复对应部署的路由。(openship.io)

你可以按以下顺序操作:

  1. 先启动目标旧版本实例;
  2. 等待健康检查通过;
  3. 用测试请求验证关键 API,而不是只访问首页;
  4. 观察新旧实例的错误日志和响应状态;
  5. 验证流式响应是否完整结束;
  6. 验证 WebSocket 是否能建立、保持并重新连接;
  7. 最后再执行流量切换;
  8. 切换后继续保留新旧日志,直到发布负责人确认恢复。

❌ 不能通过的情况包括:控制台显示健康,但接口返回 5xx;普通请求正常、流式响应中断;新连接正常、已有 WebSocket 会话全部断开;路由回到旧应用,但静态资源仍来自新版本。

后台任务与幂等性

AI SaaS 常见的隐藏风险不是网页打不开,而是任务被执行两次。OpenShip 官方页面列出了定时任务、重试、运行日志和 Worker 等能力,但具体任务是否幂等,取决于你的任务实现和状态记录。(openship.io)

回滚期间,可能出现以下并存状态:

  • 新 Worker 已领取任务,旧 Worker 又重新领取;
  • 定时任务在切换前后各触发一次;
  • 队列消息因超时重试,再次调用外部工具;
  • Agent 已产生副作用,但状态写入尚未完成;
  • 旧代码无法识别新版本写入的任务状态。

验收时要对每个关键任务保存 3 类证据:

  1. 任务 ID: 是否同一个任务被多个 Worker 领取;
  2. 状态记录: 是否经历重复的 pendingrunningcompleted
  3. 副作用结果: 是否重复发信、扣费、写文件、调用工具或修改业务数据。

发现重复消费后,不要继续观察。先停止相关 Worker 或暂停队列,再判断是否可以安全重放。无法确认副作用边界时,应将任务标记为人工复核,并由数据恢复负责人决定补偿方式。

生产验收清单

下面的清单适合放进上线审批单。每一项都要填写证据位置,不能只勾选“已完成”。

版本与配置

  • [ ] 已记录目标旧版本的提交标识、镜像摘要或部署 ID。
  • [ ] 已验证目标镜像可以在无缓存条件下重新取得。
  • [ ] 已用新实例验证旧启动命令和运行依赖。
  • [ ] 已核对回滚后实际生效的环境变量版本。
  • [ ] 已核对密钥权限、外部 API 地址和功能开关。
  • [ ] 日志中未出现密钥明文。

数据库与持久化数据

  • [ ] 已标记本次数据库迁移属于向后兼容、可逆还是破坏性迁移。
  • [ ] 已验证旧代码能读取迁移后的 Schema。
  • [ ] 已确认应用回滚不会被误认为数据库恢复。
  • [ ] 破坏性迁移已准备独立备份或时间点恢复证据。
  • [ ] 已验证恢复后的数据库能被目标版本读取。
  • [ ] 已指定数据恢复负责人。

请求与任务

  • [ ] 健康检查通过后才开始接收流量。
  • [ ] 已测试普通 HTTP、流式响应和 WebSocket。
  • [ ] 已记录切换前后的错误日志和请求结果。
  • [ ] 已检查定时任务、队列和工具调用是否重复。
  • [ ] 已用任务 ID、状态记录和副作用结果验证幂等性。
  • [ ] 已写明重复消费后的停止、去重和补偿动作。

发布结论

  • [ ] 通过上线: 五类证据完整,关键请求恢复,数据和任务没有未解释异常。
  • [ ] 限制上线: 存在已知降级,但范围、负责人和观察条件已经写清。
  • [ ] 禁止上线: 旧代码无法读取数据库、配置无法恢复、关键请求失败,或任务副作用无法确认。

关于 AI SaaS 的整体上线验收,可以结合发布审批记录补充权限、监控和告警项目。

FAQ:回滚前的关键判断

回滚后配置是否一定跟着旧版本一起变化?

不要默认会。你需要核对回滚后容器实际读取的配置版本、密钥权限和外部 API 地址。旧代码即使成功启动,只要环境变量仍指向新服务,业务依赖仍可能不兼容。验收记录中只保存配置哈希、版本号或更新时间,不要保存密钥明文。

Schema 已经改变,旧应用还能正常运行吗?

可以,但前提是旧代码能够读取迁移后的 Schema。新增字段通常可以通过向后兼容方式处理;删除字段、改类型或改变约束则可能阻断应用回退。应用版本回退不会自动恢复数据库,破坏性迁移必须另行验证备份或时间点恢复。

切换版本时怎样降低请求中断风险?

先确认旧版本实例通过健康检查,再观察普通 HTTP、流式响应和 WebSocket。不要只看控制台状态。对长连接服务,你还要验证连接排空、重新连接和会话恢复;若实际请求仍出现错误,应暂停流量切换并保留新旧版本日志。

为什么回退后同一个后台任务可能执行两次?

回滚期间新旧 Worker 可能短暂并存,定时任务、队列重试或工具调用会再次处理同一任务。你需要用任务 ID、状态记录和副作用结果确认幂等性,并提前写好停止 Worker、暂停队列、去重或补偿的动作。

上线前怎样安排一次完整的回滚演练?

在隔离环境部署一个包含配置变化、数据库迁移、后台任务和长连接的版本,再回滚到旧版本。分别保存部署日志、容器版本、配置哈希、健康检查结果、请求结果、任务状态和数据库恢复证据,最后由发布负责人决定通过、限制上线或禁止上线。

如果你把本地电脑当作唯一的生产验收环境,通常会遇到设备不持续在线、团队成员环境不一致、回滚演练和正式构建争抢资源等问题。对需要长时间保持在线的构建端或临时验收环境,这些限制会让“可重复回滚”变成一次性的人工操作。

更稳妥的做法是,把完整回滚演练放进隔离环境,再用固定的构建节点复现版本、配置和日志。若你需要临时的云端 Mac 构建或验收环境,可以查看 Mac 云端租用方案;如果团队还不确定如何选择运行环境,也可以先从 Kvmzen 服务入口了解适用边界。

限时特惠

不只是一台 Mac,是你在云端的开发基地

独享算力 · 全球节点 · 按月订阅 · 无需购置硬件

返回首页
限时优惠 点击查看套餐