Webhook 广播回答「谁没投递成功」,却不回答「哪一版技能切片该吃生产流量」。在 clustervps 多 Mac 网关上的最小纪律:比例金丝雀、semver 技能目录,以及合并 Doctor、队列与摘要的单一就绪探针

本文与《多 AZ 网关、Webhook 与令牌轮换》互补——彼篇以广播与令牌为主,本篇以流量百分比、semver 切片与晋升门闩为主。制品扇出见《rsync 矩阵》,跨区拓扑见《拆分 DNS 矩阵》

OpenClaw 多节点发布流程(动比例之前)

发布是跨网关契约,不是单机 git pull。四件套须一致:openclaw.lock 哈希、租户片段、与 lockfile 对齐的技能目录、下文合成就绪路由。顺序:shadow 上金丝雀Doctor+合并探针绿LB 微移同伴镜像审计。跳过 shadow 易出现「LB 仍绿、磁盘两套技能树」。

  • 权威源:每次晋升打 Git tag;工作树脏则拒绝 launchctl reload。
  • 并联网关:一台 writer 打标;金丝雀网关先拉;稳定网关仅在比例门闩通过后再拉。
  • Worker 与通知器:允许落后网关一个修订,但不得领先网关,否则合并探针会对技能兼容性撒谎。
#!/usr/bin/env bash
set -euo pipefail
cd /usr/local/share/openclaw-infra
/usr/bin/git fetch --tags origin
/usr/bin/git checkout "refs/tags/${PROMOTE_TAG}"
/usr/bin/shasum -a 256 openclaw.lock | /usr/bin/tee /tmp/lock.sha
/usr/local/bin/openclaw version --json | /usr/bin/tee /tmp/version.json
/usr/bin/diff -q openclaw.lock <(ssh canary-gw "cat /usr/local/share/openclaw-infra/openclaw.lock")

当 diff 为空时才允许触碰负载均衡权重;否则请停手——你即将在 AZ 之间制造分裂脑。

流量比例:clustervps 多 AZ 网关上的金丝雀门闩

金丝雀晋升是离散比例序列,不是体感。先把约百分之五的新会话打到已挂载 shadow 技能目录的网关(/var/db/openclaw/skills/nextcurrent 并列)。该比例至少跨越两个合并探针周期(常见约十分钟),同时观察网关 p95、队列深度与错误预算——与 Webhook 噪声解耦。仅当合并 JSON 中 Doctor 为绿、digest 块为净或已归类为可接受的背压时,再以10~20 点阶梯放大权重。

每一步在表格里留一行:时间戳、权重快照、技能 semver、工单号——午饭到事故之间「到底改了什么」,靠它而不是靠 Slack 翻页。

把负载均衡厂商调权用的 API/CLI 写成可复制的 shell 函数;clustervps 上常见 anycast 或 GeoDNS 前置 Mac 网关,事故时要能直接粘贴执行。

配置片段分租户:技能切片边界

切片前务必将各网关 /etc/openclaw/tenants/<tenant>/skills.d/include 顺序对齐,再让 next 指向新 semver。片段只写边界(工具命名空间、模型、配额);密钥放 /var/db/openclaw/secrets/<tenant> + POSIX ACL。

# On each gateway after git tag checkout
sudo install -d -o root -g wheel /etc/openclaw/tenants/acme/skills.d
sudo /usr/local/bin/openclaw config lint --tenant acme
sudo /bin/ln -sfn "/var/db/openclaw/skills/1.4.2" /var/db/openclaw/skills/next
sudo launchctl kickstart -k system/com.openclaw.gateway

金丝雀租户可把 skills.d/10-canary.yaml 指向 next,生产租户在审计批准前仍钉在 current——这是不切整个集群的最小按租户切片。

探针合并:Doctor、队列、摘要与技能 semver

对外 LB 仍打一条 URL,但处理器必须同时回答:磁盘声明的技能 semver是否与 openclaw.lock 一致、上一时间窗内吃到流量的租户 Doctor 是否可接受、队列深度是否落在 SLO 内。Webhook digest 行仍有价值,但只能是合并载荷里的一个字段,而不是晋升扳机——这正是与「纯广播架构」正交之处。

#!/usr/bin/env bash
set -euo pipefail
TENANT_CANARY="${TENANT_CANARY:-acme}"
SKILL_PATH="/var/db/openclaw/skills/current"
/usr/bin/readlink "${SKILL_PATH}" | /usr/bin/tee /tmp/skill_path.txt
/usr/local/bin/openclaw doctor --tenant "${TENANT_CANARY}" --json >/tmp/doctor.json
/usr/bin/curl -fsS --max-time 3 "http://127.0.0.1:9099/v1/webhook-digest" -o /tmp/digest.json
/usr/bin/python3 - <<'PY'
import hashlib, json, pathlib
blob = pathlib.Path("/tmp/doctor.json").read_bytes() + pathlib.Path("/tmp/digest.json").read_bytes()
print(json.dumps({"probe_sha256": hashlib.sha256(blob).hexdigest(),"skill_resolved": pathlib.Path("/tmp/skill_path.txt").read_text().strip()}))
PY

Doctor 黄但 semver 与 digest 仍可接受时,可返回 status: degraded:流量继续,仪表盘尖叫。semver 与 lockfile 不一致必须硬失败——Webhook 再干净也不该晋升该构建。

回滚:权重、符号链接与 launchd 一口气到位

回滚只有两根杠杆:LB 权重回到金丝雀前快照,以及 /var/db/openclaw/skills/current 指回旧 semver 目录。不要半拉子回滚:只调权重不恢复 symlink,会出现「旧流量打新技能」或相反噩梦。两杠杆都到位后,kickstart 一次网关,再等合并探针 JSON 与审计文件里归档的「好快照」对齐。

#!/usr/bin/env bash
set -euo pipefail
/usr/bin/scp stable-gw:/var/db/openclaw/audit/last_good_weights.json /tmp/weights.json
./lb_restore_weights.sh /tmp/weights.json
sudo /bin/ln -sfn "/var/db/openclaw/skills/${ROLLBACK_SEMVER}" /var/db/openclaw/skills/current
sudo launchctl kickstart -k system/com.openclaw.gateway
/usr/bin/curl -fsS http://127.0.0.1:8088/readyz | /usr/bin jq .

回滚演练与跨区制品 rsync 矩阵里的制品卫生配套,避免 LB 还指错 AZ 时你在跟 rsync 赛跑。

审计:安全团队能直接 grep 的追加式 JSONL

每步调权在 writer 上追加一行到 /var/db/openclaw/audit/promotions.jsonl(建议夜间同步对象存储):actorticket、前后 semver、权重快照、probe_sha256

/usr/bin/printf '%s\n' \
  "{"ts":"$(date -u +%Y-%m-%dT%H:%M:%SZ)","actor":"${USER}","ticket":"${TICKET}","from":"1.4.1","to":"1.4.2","weights":"${WEIGHT_BLOB}","probe_sha256":"${PROBE_SHA}"}" \
  | /usr/bin/tee -a /var/db/openclaw/audit/promotions.jsonl

审计追问「改了什么」时,用 jq 过滤 JSONL,而不是翻 Slack。

常见问题:金丝雀优先 vs Webhook 优先

还需要 notifier digest 吗?需要——把它放进合并探针,便于看到合作方系统性故障。但不要仅凭 digest「健康」就放大流量;semver 与 Doctor 必须先达成一致。

只有单个租户想尝新技能?把其片段留在金丝雀池,并用 LB 粘滞 cookie/头把该租户队列钉到金丝雀网关,其余租户维持稳定权重。

最少几台 Mac?三台 clustervps 主机仍是最小诚实演练:稳定 AZ-A、稳定 AZ-B,以及先吃比例流量再在同伴侧镜像的金丝雀网关。

本文仅为运维建议。OpenClaw 具体发行版的参数会随版本变化,请在 staging 对照已安装构建校验 flag;负载均衡 API 因厂商而异,文中 shell 片段是模式而非可直接粘贴的密钥。
并联集群容量

按可用区配网关,而不是按「英雄工程师」

当每个 AZ 都有独占 Mac、能容纳 shadow 技能树与合并探针时,金丝雀演练才不再吓人。对比 clustervps 套餐,在缺少金丝雀席位的区域再加一台并联节点,把比例打在真机上而不是借用笔记本。准备下单可走购买页;值班手册旁请固定帮助中心站点首页链接,动流量前全队先对齐 SSH 路径。

增加一台并联网关 Mac 查看套餐 帮助中心