智能体网关承接「至少一次」投递,若缺少幂等键,写文件、扣款、发券等副作用会被放大成事故。2026 年主流 OpenClaw 将幂等前移到网关,用 Redis 原子认领与重放封装把副作用挡在执行器之外。请同时阅读 JSON Schema 网关校验、nginx 滚动排空、429 与 Retry-After 策略 与 读取超时诊断,再在正文展开落地细节。
键语法与归一化
统一采用 HTTP 头 Idempotency-Key 或 JSON 字段 idempotency_key。对 base64url 解码后熵少於 16 字节的键直接拒绝,防止枚举猜测。线长上限建议 128 个 ASCII 字符,避免日志与负载均衡器被超长键拖垮。归一化流程:去空白、按文档约定处理大小写、拒绝含控制字符的键。将归一化结果做 SHA-256 哈希写入 Redis 字段名,既保留隐私又稳定键空间。
幂等记录必须绑定 (tenant_id, route_id, key_hash, schema_version)。当 Schema 版本 升级时,有意让旧重放失效,避免把「旧响应形态」误送给新校验器。
Redis 原子认领与 Lua
第一次请求执行 SET idempo:{tenant}:{hash}:claim NX EX 172800,成功则当前 worker 拥有槽位,可向上游发起真实调用。竞争者拿到空值时,应读取已写入的重放封装并直接返回,不得再次触发副作用。默认 172800 秒即四十八小时;若夜间批处理在第三天仍可能合法重试,把 EX 提到 259200 秒(七十二小时),同时扩容 Redis 监控与内存告警阈值。
# OpenResty 伪代码:先认领再转发
local key = "idempo:" .. tenant .. ":" .. idem_hash
if redis:set(key..":claim", worker_id, "NX", "EX", 172800) == nil then
return replay(key)
end
proxy_pass http://openclaw_upstream;
顺序必须是「认领 → 上游执行 → 写入重放」。若上游已成功但写封装失败,需要补偿日志,用同一哈希键回放修复,避免客户看到「超时却扣款」。
拓扑矩阵:本地与集群
| 形态 | 优势 | 风险 | 适用 |
|---|---|---|---|
| 进程内 LRU | 亚毫秒查询 | 多副本脑裂 | 单机开发 |
| Redis 集群 | TTL 与原子操作成熟 | 热点键 | 生产默认 |
| 关系型 advisory lock | 审计友好 | 锁竞争与延迟 | 强监管金融 |
| etcd 租约 | 服务网格协同 | 运维复杂 | 已上 mesh 的企业 |
对 OpenClaw 而言,Redis 仍是性价比最高的共享真相源;按租户做 key 前缀分片,避免「顶流租户」拖垮单槽。
TTL:172800 与 259200 秒
四十八小时与公开支付接口惯例一致;七十二小时覆盖跨周末对账。TTL 到期后必须视为全新操作,SDK 要在用户点击「重新发起」时轮换键。法务材料、对外 SLA 与 Redis EX 必须一致,审计会核对这三处文本。
重放封装与校验和
封装内保存状态码、可安全重放的响应头子集,以及正文 BLAKE3 或 SHA-256 校验和。正文超过 1 MiB 时写入对象存储,只在 Redis 存指针。流式工具输出要把分片序号写入封装,防止半流被误判完成。若重放校验失败率超过 0.01% 且持续十分钟,按 Sev-2 处理,通常意味着序列化版本或压缩层漂移。
nginx 协同与超时
在边缘终止 TLS,注入归一化头,并把哈希衍生值作为内部可信头传给 OpenClaw。排空 期间保持 Redis 连接串不变。将 proxy_read_timeout 设得略高于网关内部「幂等上游预算」,并与 读超时诊断 手册一致,避免 nginx 与网关双重误判。
上线清单
- 为所有写路由打标
requires_idempotency=true并录入服务目录。 - SDK 默认生成 UUIDv4,拒绝短于 22 个 base64url 字符的人工键。
- 生产 Redis 至少 三主,AOF 采用
everysec折中持久化。 - 集成测试并发 二十 路重复,断言上游副作用计数仅增加一次。
- 演练:排空 50% Pod 的同时灌入重复流量,验证共享存储。
- 文档化错误码:过期键、正文不匹配、租户漂移。
- 观测:重放占比、认领 p99、每分钟驱逐键数量。
遥测与基数控制
指标包括 idempo_claim_total、idempo_replay_total、idempo_conflict_total。租户标签需哈希分桶,防止 Prometheus 基数爆炸。单独跟踪 Redis 往返,避免把缓存退化误判为模型变慢。若重放占比超过 35% 超过三十分钟,多半是客户端死循环而非健康去重。
跨区域部署若将幂等记录集中在单一区域,要写明复制延迟上限,避免容灾切换后客户端读到旧重放。每周检视冲突率与自定义错误码分布,将异常租户加入人工复核队列,并在周报附上近七日 p99 认领延迟,方便财务与平台共用同一套证据链。
分区与失败策略
Redis 不可用时要明确「失败关闭」或「失败打开」。资金类必须失败关闭返回 503,并提示退避;内网沙箱可失败打开但必须大红横幅。客户端重试上限建议 五次,基础退避封顶 32 秒;若上游返回 Retry-After,应取更大值,详见 429 指南。
常见问题
GET 是否需要幂等键?
一般不需要;但禁止用 GET 伪装写操作,敏感动作一律 POST。
同一键能否跨路由?
不能,必须在存储元组中包含路由标识。
离线队列如何处理?
任务入队时生成键,_flush 时复用,避免重复入账。
Apple Silicon Mac mini 在能耗与静音上适合 7×24 网关演练:本机 Redis、nginx 与 OpenClaw 二进制与生产路径一致,macOS 的 launchd、钥匙串与沙箱行为亦与真机对齐,减少「笔记本能跑、机房失败」的落差。MacHTML 云主机日租约 16.9 美元,可在不影响客户流量的情况下回放捕获的重复洪峰、验证 Lua 脚本与 Redis 故障切换。
把幂等演练固定在云 Mac 上,还能并行执行 TLS 探针与 openssl s_client 检查,让安全与平台共用同一台「可弄脏」的 Apple Silicon 环境,缩短审计答疑周期。