跳转到内容
use-cases / recurring-webhook-replay / hero
CRON · FILES · EXEC

把今天早上的 webhook 在明天同一时间重放一次

把你真实的 Stripe webhook 指向一个 hoody-files URL,持续三十分钟。这个目录现在装着十四个 JSON 文件 —— 击中生产的每一个 payload,字节级一致。一条 cron 条目运行一个 exec 脚本,在每个工作日上午 9 点把它们 POST 回 staging。这个调度下周六过期并自删。

阅读 Cron API
use-cases / recurring-webhook-replay / pipeline

捕获一次,以文件持久化,按时间表重放

整个流程就是三个 URL。生产流量到达捕获 URL。文件落进 hoody-files。Cron 走一遍文件夹并把请求体 POST 回 staging。没有 broker、没有队列、没有重放服务 —— 只有一个目录和一个时间表。

PIPELINE无 broker · 无队列
01 · CAPTURE

生产 webhook 变成一次 PUT

把你的 Stripe / Intercom / GitHub webhook URL 设为一个 hoody-files 路径。每个事件作为 PUT 到达,落地为一个以时间戳命名的 JSON 文件。这个目录就是录音。

02 · PERSIST

每天一个文件夹,可作为 URL 寻址

文件持久化在磁盘上;每个文件都有自己的 URL。在浏览器里浏览这个目录、通过 API 列出它,或者用 curl shell 进去。这份录音是一个事实,你可以 cat、scp 或版本化它。

03 · REPLAY

一条 cron 条目走一遍文件夹

POST 一条受管理 cron 条目,调度 0 9 * * 1-5,命令 bash /scripts/replay.sh /webhooks/2026-05-03。脚本列出目录并按时间戳顺序把每个文件 POST 回 staging。

捕获和重放在不同日子里是同一种协议。录下字节的东西,正是回放它们的东西。没有 JSONL 解析器、没有 sidecar、没有要学的录音格式 —— 文件夹里的文件,按时间排序。

use-cases / recurring-webhook-replay / mechanism

两次 POST 加一个文件夹

捕获是每个 webhook 事件一次 PUT。重放是对 cron API 一次 POST。Hoody Files 持有录音;Hoody Cron 按时间表走一遍;hoody-exec 运行做 POST 的 bash 脚本。三个服务,中间没有胶水。

stripe → hoody-files
PUT · capture
# point your real webhook at hoody-files
curl -X PUT \
  https://files.containers.hoody.com/webhooks/2026-05-03/stripe-08-15-22.json \
  --data-binary @-

# 30 minutes later, the directory holds 14 files
HTTP/1.1 201 Created
webhooks/2026-05-03/stripe-08-15-22.json
安排重放
POST · cron entry
# one cron entry replays the morning at 9am, mon-fri
curl -X POST \
  https://cron.containers.hoody.com/api/v1/cron/users/me/entries \
  -d '["schedule":"0 9 * * 1-5","command":"bash /scripts/replay.sh /webhooks/2026-05-03","expires_at":"2026-05-10T09:00:00Z"]'

HTTP/1.1 201 Created
{ "id":"f0a8", "schedule":"0 9 * * 1-5", "expires_at":"2026-05-10T09:00:00Z" }

捕获端只在某个周五早上跑一次。重放端每个工作日跑一次,直到下周六 cron 条目的 expires_at 字段把调度删除。你把一个 PUT URL 写进 webhook 配置,把一个 POST 写进 cron API —— 这就是整个负载测试。

use-cases / recurring-webhook-replay / powers

这能给你 load-test fixture 给不了的东西

合成流量是你想象中请求该有的样子。捕获流量是真正到达过的样子。同样的字段名、同样的边界情况、同样的意外。

FIDELITY

真实的 payload 形状,不是你的猜测

录音捕获 Stripe 真正发出的 JSON —— 包括每个可空字段、每个意料外的事件类型、每个你忘了的 customer_id 格式。你的 handler 面对昨天让它失败的那些 payload。

TIMING

和生产一样的时段压力

Cron 表达式 0 9 * * 1-5 让重放落在你真实用户实际使用系统的那个小时。被测的 handler 面对早高峰,以及同样的缓存、同样的 cron 邻居、同样吵闹的 DB。

REPEATABILITY

重放到 bug 消失为止

文件夹是不可变的;cron 每个工作日跑,直到 expires_at。如果 handler 在周二的运行还坏,你修一下,让周三的运行证明它已经修好。每次输入相同 —— 唯一改变的是 handler。

use-cases / recurring-webhook-replay / capacity

调度承诺了什么

数字来自 Hoody Cron 受管理条目 API 和标准 cron 表达式规范 —— 不是凭空捏造的基准。

  1. FIELDS PER ENTRY5

    标准 5 字段 cron 表达式 —— 分钟、小时、月内日、月、周内日。1985 年你用过的同一种语法,2026 年依然安排重放。

  2. ENTRIES PER PAGE200

    GET /users/[user]/entries 一次最多分页返回 200 条受管理条目。每个环境六十三个重放调度,完全在预算之内。

  3. POST TO CREATE1

    用一次 POST /users/me/entries 创建周期性重放 —— schedule、command、expires_at。之后用 PATCH 静音;用 DELETE 退役;expires_at 自动替你退役。

限制以 Hoody Cron Managed Entries API 为准:标准 5 字段 cron 表达式加 @daily / @hourly 宏,分页每页最多 200 条,expires_at 可选,过了截止时间会自动禁用条目。

use-cases / recurring-webhook-replay / punchline

生产流量,录一次,按时间表重放。

已捕获 · 周五 08:00已重放 · 周一到周五 09:00
WHAT THE OLD LOAD TEST LOOKED LIKEk6 script · faker · imagined payload shapes你对 stripe 发什么的猜测 · 每季度再猜一次
WHAT IT LOOKS LIKE NOWPUT files/webhooks/[day] · POST cron/entries 0 9 * * 1-5击中过生产的真实字节 · 由一条调度重放
阅读 Cron API
use-cases / recurring-webhook-replay / replaces

这取代了什么

重放 webhook 流量的常规工具 —— 录制器、重放服务、定时 mock。每一个都是 SaaS、sidecar 或你需要照看的脚本。hoody-files + hoody-cron 这一对都不是。

  • ngrok webhook recording为录制本可写到磁盘的请求开一份 SaaS 套餐
  • Hookdeck event replays为本就是文件夹里的文件而开一个事件路由服务
  • custom replay scripts你写过一次,然后忘了怎么调度的胶水代码
  • Postman scheduled mocks买一个监视器席位,只为对自己的 staging 发 HTTP
  • mocking servers in test envs在真后端旁边再维护第二个后端
  • manual webhook fuzzing你早上 9 点坐在终端里粘 payload
use-cases / recurring-webhook-replay / cta

捕获周五的流量。安排下周的重放。等实验结束时,让 cron 条目自己过期。

阅读 Cron API
use-cases / recurring-webhook-replay / related

阅读其他内容