ObjectOS
配置

Webhooks

出站 webhook 投递、签名与重试。

Webhooks

ObjectOS 为出站 webhook 采用持久化的 outbox 模型。当 webhook 插件启用时,业务变更会将一条投递记录入队,由后台 dispatcher 带重试地完成投递——因此响应缓慢或不可用的接收方永远不会阻塞发起方事务。

启用 webhooks

Webhooks 是一项可选能力。部署的 ObjectOS 镜像必须包含 @objectstack/plugin-webhooks,并且应用 artifact 必须注册 webhook 订阅(通常作为 sys_webhook 对象的记录)。

启用后,Console 中会出现两个对象:

对象用途
sys_webhookWebhook 订阅(目标 URL、事件过滤器、secret、状态)
sys_webhook_delivery投递日志(URL、响应码、尝试次数、重试时间戳)

投递语义

  • 至少一次。 投递在发生瞬时失败后可能被重试;接收方必须是幂等的。
  • 持久化。 投递记录会在 ObjectOS 重启后保留,因为它们存储在业务数据库中。
  • 分区。 每个 dispatcher worker 认领 outbox 的一个分区,使部署能够横向扩展投递而不会重复投递。
  • 有界重试。 失败的投递会以退避策略重试,直至达到可配置的上限;耗尽重试的记录会保留在 sys_webhook_delivery 中以供检查。

签名

每次投递都携带标识性请求头,使接收方能够路由、去重并校验它:

X-Objectstack-Event:     <event type, e.g. data.record.created>
X-Objectstack-Delivery:  <delivery id — use as your idempotency key>
X-Objectstack-Attempt:   <attempt number, starting at 1>

当 webhook 订阅设置了 secret 时,ObjectOS 还会为每个请求签名:

X-Objectstack-Signature: sha256=<hex hmac>

签名为 HMAC-SHA256(secret, body),基于原始请求体计算。在接收端信任载荷前先校验它:

import { createHmac, timingSafeEqual } from 'node:crypto';

function verify(body, signatureHeader, secret) {
  const expected = 'sha256=' + createHmac('sha256', secret).update(body).digest('hex');
  return timingSafeEqual(Buffer.from(signatureHeader), Buffer.from(expected));
}

轮换 secret 的方式:使用新 secret 创建一个新订阅,在过渡期同时运行两者,然后停用旧订阅。

对接收方的要求

  • 在数秒内返回 2xx4084295xx 响应(或超时/传输错误)是可重试的,会以退避策略重试。任何其他 4xx 都被视为永久性失败,并在不再重试的情况下转入 dead
  • 在看到 2xx 之前,dispatcher 不会将投递标记为成功,因此失败的接收方会使该记录保留在 sys_webhook_delivery 中,以供检查或重新投递。
  • 保持幂等——基于 X-Objectstack-Delivery 请求头(delivery id)或你自己在载荷中的 event id 去重。

失败处理

出错时:

  1. 检查 sys_webhook_delivery 中的记录——statusresponse_coderesponse_bodyattempts 均有记录。
  2. 确认从 ObjectOS 到接收方的出站网络可达。
  3. 如果接收方永久变更了,更新订阅 URL 并从 Console 重新投递该记录。
  4. 用于事件复盘:审计日志(sys_audit_log)记录订阅编辑,但不记录载荷——载荷保留在 outbox 中。

运维建议

  • 不要把 secret 放进 webhook URL(query string 会被记录)。
  • 使用独立的接收方主机名,便于在边缘屏蔽以卸载流量时不影响主应用。
  • 关注 dispatcher 滞后——outbox 不断增长通常意味着接收方降级。

On this page