GH GambleHub

Webhook交付保证

Webhooks是通过HTTP(S)从系统到订户的异步通知。网络不可靠:答桉丢失,数据包重复或脱序。因此,交付保证不是"通过TCP"构建的,而是基于webhook协议和域幂等级的。

关键目标:提供按键顺序(在需要时)的在线交付,为订户提供用于等效处理的材料和用于还原的回收工具。


1)保障水平

Best-effort是一次尝试,没有后退。仅适用于"不重要"事件。
One-least-once(推荐)-可以重复和退出订单,但事件将在合理的时间内交付,但前提是订户可用。
Effectively-exactly-once(在效果级别)-通过在订户/发件人侧面的幂等和减速存储相结合来实现。在HTTP传输上,"exactly-once"是不可能的。


2)webhook合同: 最低要求

标题(示例):

X-Webhook-Id: 5d1e6a1b-4f7d-4a3d-8b3a-6c2b2f0f3f21  # глобальный ID события
X-Delivery-Attempt: 3                 # номер попытки
X-Event-Type: payment.authorized.v1          # тип/версия
X-Event-Time: 2025-10-31T12:34:56Z          # ISO8601
X-Partition-Key: psp_tx_987654            # ключ порядка
X-Seq: 418                      # монотонный номер по ключу
X-Signature-Alg: HMAC-SHA256
X-Signature: t=1730378096,v1=hex(hmac(secret, t        body))
Content-Type: application/json
身体(示例):
json
{
"id": "5d1e6a1b-4f7d-4a3d-8b3a-6c2b2f0f3f21",
"type": "payment.authorized.v1",
"occurred_at": "2025-10-31T12:34:56Z",
"partition_key": "psp_tx_987654",
"sequence": 418,
"data": {
"payment_id": "psp_tx_987654",
"amount": "10.00",
"currency": "EUR",
"status": "AUTHORIZED"
},
"schema_version": 1
}

收件人要求:在签名缓冲和验证后快速回答"2xx"并异步进行业务处理。


3)顺序和因果关系

按键排序:保修仅在单个"partition_key"(例如,"player_id","wallet_id","psp_tx_id")内部"不会离开"。
全球秩序没有得到保障。
发件人侧面是按键序列化的队列(单个消费者/sharding),收件人侧面是inbox,带有"(源,event_id)",可选地等待错过的"seq"。

如果跳过是关键的-提供pull-API "GET/events?after=checkpoint的"追赶和钻探"状态。


4)相似性和重复数据消除

每个Webhook都带有稳定的"X-Webhook-Id"。
收件人存储"inbox(event_id)":PK-'source+event_id';重播→无操作。
当事件第一次出现"视图"时,副作用(写入DB/钱包)仅执行一次。
对于"有效果"命令,请使用Idempotency-Key和Retrace窗口期间的结果缓存。


5)Retrai,backoff和窗户

Retraes政治(参考):
  • 在"5xx/timeout/connection error/409-Conflict (retryable)/429"上转播。
  • 除了"409/423/429"(并且仅在一致的语义下)之外,不要重述"4xx"。
  • 指数backoff+ full jitter: 0。5s, 1s, 2s, 4s, 8s, …最多'max=10-15 min';中继窗口的TTL:例如72小时。
  • 尊重收件人的"Retry-After"。
  • 有一个共同的截止日期:"承认事件未交付"并将其转换为DLQ。
yaml retry:
initial_ms: 500 multiplier: 2.0 jitter: full max_delay_ms: 900000 ttl: 72h retry_on: [TIMEOUT, 5xx, 429]

6) DLQ и redrive

DLQ是有毒或过期的TTL事件的"墓地",具有完整的元信息(标题,标题,错误,尝试,散列)。
基于Web 的控制台/API for redrive(点对点重新交付),可选用endpoint/secret编辑。
具有优先级的Rate-tended redrive和batch-redrive。


7)安全性

mTLS(如果可能)或TLS 1。2+.

身体签名(带有per tenant/endpoint秘密的HMAC)。验证:

1.从标题中检索"t" (timestamp),检查滑动窗口(例如,± 5分钟)。

2.还原签名字符串body',比较恒定时间的HMAC。
反复制:存储'(event_id, t)'并拒绝太旧/重复的请求。
秘密轮换:在轮换期间支持两个活跃的秘密。
另外:IP-allowlist,"User-Agent"标题,原始IP的删除。

8)配额,比例限制和公平

Fair-Queue per tenant/subscriper: 确保一个订户/tenant不会得分。
出站流量和per-endpoint的配额和爆破限制。
对"429"的反应:尊重"Retry-After",旋转;长时间限制为degrade(仅发送关键事件类型)。


9)订阅生命周期

Secret rotation: `current_secret`, `next_secret` с `switch_at`.

注册/验证:POST endpoint →挑战/响应或乐队外确认。
Lease(根据需要):签名有效期为"valid_to";延长是显而易见的。
Test ping:在打开主拓扑之前检查路由的人工事件。
健康样本:定期进行HEAD/GET,并进行简介检查和TLS。


10)模式的演变(事件版本)

事件类型的转换: '付款。authorized.v1` → `…v2`.

进化-进化(新字段→ API的MINOR版本),破解→新类型。
电路寄存器(JSON-Schema/Avro/Protobuf)+在发送前自动验证。
标题"X-Ivent-Type"和主体中的"schema_version"字段都是必需的。


11)可观察性和SLO

度量(按类型/tenant/订阅者):
  • `deliveries_total`, `2xx/4xx/5xx_rate`, `timeout_rate`, `signature_fail_rate`.
  • "attempts_avg","p50/p95/p99_delivery_latency_ms"(从发布到2xx)。
  • `dedup_rate`, `out_of_order_rate`, `dlq_rate`, `redrive_success_rate`.
  • `queue_depth`, `oldest_in_queue_ms`, `throttle_events`.
SLO(参考):
  • 交货比例≤ 60 c(p95)-99。5%用于关键事件。
  • DLQ ≤ 0.24小时1%
  • Signature failures ≤ 0.05%.

Логи/трейсинг: `event_id`, `partition_key`, `seq`, `attempt`, `endpoint`, `tenant_id`, `schema_version`, `trace_id`.


12)发件人参考算法

1.将事件写入事务性outbox。
2.定义partition_key和seq;放在队列中。
3.Vorker按键,生成查询,签名,随时间表(connect/read)发送。
4.在"2xx"-承认交付,固定潜伏期和seq-checkpoint。
5.根据"429/5xx/timeout",根据该政策。
6.通过TTL → DLQ和alert。


13)参考处理程序(收件人)

1.接受请求,检查TLS/proto。
2.签名验证和时间窗口。
3.快速ACK 2xx(同步写入本地inbox/队列后)。
4.异步修补程序读取"inbox",检查"event_id"(擦除),如果需要-在"partition_key"内通过"seq"排序。
5.为reconcile编写"offset/seq checkpoint"来执行效果。
6.如果出现错误,则为本地转发;"有毒"任务→带有警报的本地DLQ。


14) Reconcile(子弹回路)

对于"不可阻挡"事件:
  • `GET /events?partition_key=...&after_seq=...&limit=...'-放弃所有错过的。
  • 令牌支票:'after=opaque_token'而不是seq。
  • 相同的"event_id",新的"t"上的相同签名。

15)有用的标题和代码

2 xx-接受(即使以后进行业务处理)。
410 Gone-endpoint已关闭(发送者停止交付并将订阅标记为"存档")。
409/423-暂时阻止资源→ retray是明智的。
429-常常→颤抖和后退。
400/401/403/404-配置错误;停止retrai,打开tiket。


16)多重特南特和地区

单独的per tenant/endpoint队列和限制。
数据驻留:从区域发送数据;"X-Tenant","X-Region"的端到端标题。
故障隔离:一个订户的下降不会影响其他订户(separate pools)。


17)测试

合同测试:固定的实体/签名示例,验证验证。
混乱:丢弃/复制,交换顺序,网络延迟,"RST","TLS"错误。
载荷:暴风雨,p95/p99测量。
安全:反倒带、过时的时间戳、错误的秘密、轮换。
DR/Replay:在孤立的展位中从DLQ中大量重播。


18)花花公子(runbooks)

1."signature_fail_rate"的增长'

检查"tolerance"过时的时钟漂移,秘密的轮换;暂时启用"dual secret"。

2.队列正在老化('oldest_in_queue_ms' ↑)

增加窃听者,包括关键斧头的优先级,暂时降低"嘈杂"类型的频率。

3.订阅者的风暴"429"

在尝试之间包括trottling和暂停;移动不太关键的事件类型。

4.大众的"5xx"

打开特定端点的circuit breaker,转换为defer&batch模式;向订户发出信号。

5.DLQ填充

停止非关键发布,启用低RPS的击球重播,提高订阅所有者的差异。


19)典型错误

同步重处理,直到2xx回应→ retrai和重复。
没有主体/时间窗口签名,→存在备用/反射漏洞。
缺乏"event_id"和"inbox" →是无法实现的。
尝试"全局秩序"→永久队列锁定。
没有刺伤/限制的猎犬→事件增加(thundering herd)。
所有订户的单一共享池→"嘈杂"地放置所有人。


20)售前支票清单

  • 合同:'event_id'、'partition_key'、'seq'、'event_type。vN', HMAC签名和timestamp。
  • 发件人:outbox,按键序列化,带有backoff+jitter,TTL,DLQ和redrive的转发。
  • 收件人:快速写入inbox+2xx;等效处理;本地DLQ。
  • 安全性:TLS,签名,反倒带,双秘密,轮换。
  • 配额/限制:fair-queue per tenant/endpoint,尊重"Retry-After"。
  • Reconcile API和Checkpoints;订户文件。
  • 可观察性:p95/流/错误/DLQ,通过"event_id"跟踪。
  • 事件转换和模式演变政策。
  • 事件花花公子和"按钮"全局暂停/解冻。

二.结论

可靠的webhooks是HTTP之上的协议,而不仅仅是"使用JSON的POST"。明确的合同(ID,订单密钥,签名),相等性,带有夹具的背包,公平的队列和精心设计的花花公子将"最佳案例"转换为可预测和可衡量的交付机制。按键+reconcile建立at-least-once+顺序,系统将安静地通过网络、负载峰值和人为错误。

Contact

联系我们

如需任何咨询或支持,请随时联系我们。我们随时准备提供帮助!

开始集成

Email — 必填。Telegram 或 WhatsApp — 可选

您的姓名 可选
Email 可选
主题 可选
消息内容 可选
Telegram 可选
@
如果填写 Telegram,我们也会在 Telegram 回复您。
WhatsApp 可选
格式:+国家代码 + 号码(例如:+86XXXXXXXXX)。

点击按钮即表示您同意数据处理。