Files
memind/docs/release-canary-103.md
john 473ad80882
Memind CI / Test, build, and release guards (push) Has been cancelled
fix: route portal canary through isolated edge tunnel
2026-07-26 20:30:56 +08:00

3.7 KiB
Raw Permalink Blame History

103 用户级灰度发布

Portal 的首个生产动作必须是用户级灰度,不能直接整包替换稳定版本。

运行拓扑

组件 地址 说明
稳定 Portal 103:8081 105 当前直接回源 58.38.22.103:8081;灰度发布不替换该进程
灰度路由器 103 127.0.0.1:18082 避开已占用的 18080;只通过专用灰度隧道暴露给 105
灰度边缘隧道 105 127.0.0.1:19082 反向 SSH 到 103 的 18082;不复用已退役的 19081 链路
候选 Portal 127.0.0.1:18081 独立、无源码 runtime;使用被动运行时模式
候选 goosed 127.0.0.1:18015 独立容器并挂载候选 runtime,不重建稳定 9 个容器

候选 Portal 通过 MEMIND_PORTAL_H5_ROOT 共享经审计的持久数据和数据库,但 MEMIND_RUNTIME_ROLE=candidate 会禁止重复启动 MindSpace、Plaza、提醒、订阅续期和 Agent 恢复扫描等单例后台任务。

身份和回落规则

  • john:按数据库中的唯一用户名或用户 ID 匹配。
  • 微信用户“唐”:只按绑定微信身份的唯一账号标识 wx_ul610et8 匹配;该值在生产库中是唯一 username/slug,不是显示昵称。
  • 显示昵称永远不参与路由。
  • Cookie 会话通过 h5_login_sessions 的 token hash 只读解析。
  • 微信回调通过 FromUserNameh5_user_wechat_identities 只读解析到绑定账号,再用唯一账号标识匹配。
  • 未命中、无身份、过期/撤销会话、数据库异常:走稳定版本。
  • 候选 /api/status 不健康:自动走稳定版本。
  • SSE、附件、公开页和普通 API 均由同一反向代理转发;微信 XML body 必须原样保留。

发布入口

候选必须来自干净且等于 origin/main 的完整 mainCI 成功,并具有与 .runtime/portal 完全一致、未过期的 187 项 Gate report。

bash scripts/release-portal-canary-prod.sh --yes

该脚本按顺序执行:

  1. 验证源码、分支、远端主线、Gate report 和 artifact hash。
  2. 执行 103 只读预检。
  3. 上传经过验证的候选包。
  4. 创建稳定 live 全量备份、持久目录备份和 105 两份活动 nginx 配置备份,并校验完整性。
  5. 启动独立候选 goosed、候选 Portal 和灰度路由器。
  6. 验证不可变身份配置、稳定/候选健康和路由器诊断。
  7. 启动独立的 105:19082 -> 103:18082 灰度隧道并从 105 验证。
  8. 短暂阻止新 Agent Run,排空活动任务。
  9. 逐文件原子替换、验证并 reload 105 nginx,把活动上游从 58.38.22.103:8081 切到 127.0.0.1:19082
  10. 主动停止候选,证明目标身份会自动回落稳定版,再恢复候选。

任一步失败都会把 105 nginx 恢复到稳定 58.38.22.103:8081,停止灰度隧道和候选服务, 并保留候选目录与备份证据。活动 nginx 配置变更只能由已提交的发布脚本执行,禁止在线手改。

回滚

bash scripts/rollback-portal-canary-prod.sh --yes

回滚只执行以下动作:

  • 把 105 两份活动 nginx 上游恢复到稳定 Portal 58.38.22.103:8081 并验证 reload。
  • 停止灰度隧道、灰度路由器、候选 Portal 和候选 goosed。
  • 清除发布排水标记。
  • 验证稳定 Portal 和 105 HTTPS 入口健康。

不会删除候选目录、备份或稳定运行目录。

全量晋升

scripts/release-portal-runtime-prod.sh 仍是整包替换脚本,不能把“灰度路由器已实现” 解释为自动获得全量切换权限。全量晋升必须使用同一 commit 和 artifact,保留灰度验收 证据,并再次取得明确批准;在晋升入口完成对应证据校验前,该脚本继续硬阻断非 dry-run。