Webhook 接进队列异步处理,怎么设计才不丢
现象#
改成「先入队再回 200」后响应降到 50ms,但发版时队列里的事件没了,订单同步少一批,日志里没有任何错误。
原因#
- 用了进程内内存队列,发版或 OOM 重启时未消费的消息直接消失
- 先回 200 再入队,入队失败也不回滚,Shopify 认为成功不会重试
- 队列没有死信与重试上限,一条坏消息反复重投堵住整个消费者
- 消费者按至少一次投递却没做幂等,重投时重复写业务数据
处理步骤#
- 入队换成持久化队列,例如
SQS、Pub/Sub或 Redis Streams - 顺序改成写队列成功后再回 200,入队失败直接回
500 - 消费者以
X-Shopify-Webhook-Id为幂等键,重复消息直接 ack - 配置死信队列与最大重投次数,超限告警而不是无限重投
- 在队列有积压时重启消费者,确认
ack数与积压数一致
验收标准#
发版期间积压消息在重启后全部消费,业务表无重复行,死信队列为空。
本文由 风格技术 技术团队整理,适用于 Shopify 标准版与 Plus 店铺。Shopify 平台能力迭代较快,具体操作路径与字段以官方文档和店铺后台实际版本为准。