
一台服务器上运行 60 个容器
一个裸金属服务器运行数十到数百个 Hoody 容器。KSM 和 BTRFS 去重使边际成本接近零。
把你真实的 Stripe webhook 指向一个 hoody-files URL,持续三十分钟。这个目录现在装着十四个 JSON 文件 —— 击中生产的每一个 payload,字节级一致。一条 cron 条目运行一个 exec 脚本,在每个工作日上午 9 点把它们 POST 回 staging。这个调度下周六过期并自删。
{ "id": "evt_3OHk8ZJs2k9aXq1vQ", "type": "payment_intent.succeeded", "created": 1714723522, "data": { "object": { "id": "pi_3OHk8ZJs2k9aXq1v0K7rT4mB", "amount": 4900, "currency": "usd", "status": "succeeded" } } }
由你真实的 webhook 捕获 · 由一条 cron 条目重放
整个流程就是三个 URL。生产流量到达捕获 URL。文件落进 hoody-files。Cron 走一遍文件夹并把请求体 POST 回 staging。没有 broker、没有队列、没有重放服务 —— 只有一个目录和一个时间表。
把你的 Stripe / Intercom / GitHub webhook URL 设为一个 hoody-files 路径。每个事件作为 PUT 到达,落地为一个以时间戳命名的 JSON 文件。这个目录就是录音。
文件持久化在磁盘上;每个文件都有自己的 URL。在浏览器里浏览这个目录、通过 API 列出它,或者用 curl shell 进去。这份录音是一个事实,你可以 cat、scp 或版本化它。
POST 一条受管理 cron 条目,调度 0 9 * * 1-5,命令 bash /scripts/replay.sh /webhooks/2026-05-03。脚本列出目录并按时间戳顺序把每个文件 POST 回 staging。
捕获和重放在不同日子里是同一种协议。录下字节的东西,正是回放它们的东西。没有 JSONL 解析器、没有 sidecar、没有要学的录音格式 —— 文件夹里的文件,按时间排序。
捕获是每个 webhook 事件一次 PUT。重放是对 cron API 一次 POST。Hoody Files 持有录音;Hoody Cron 按时间表走一遍;hoody-exec 运行做 POST 的 bash 脚本。三个服务,中间没有胶水。
# 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
# 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 —— 这就是整个负载测试。
合成流量是你想象中请求该有的样子。捕获流量是真正到达过的样子。同样的字段名、同样的边界情况、同样的意外。
录音捕获 Stripe 真正发出的 JSON —— 包括每个可空字段、每个意料外的事件类型、每个你忘了的 customer_id 格式。你的 handler 面对昨天让它失败的那些 payload。
Cron 表达式 0 9 * * 1-5 让重放落在你真实用户实际使用系统的那个小时。被测的 handler 面对早高峰,以及同样的缓存、同样的 cron 邻居、同样吵闹的 DB。
文件夹是不可变的;cron 每个工作日跑,直到 expires_at。如果 handler 在周二的运行还坏,你修一下,让周三的运行证明它已经修好。每次输入相同 —— 唯一改变的是 handler。
数字来自 Hoody Cron 受管理条目 API 和标准 cron 表达式规范 —— 不是凭空捏造的基准。
标准 5 字段 cron 表达式 —— 分钟、小时、月内日、月、周内日。1985 年你用过的同一种语法,2026 年依然安排重放。
GET /users/[user]/entries 一次最多分页返回 200 条受管理条目。每个环境六十三个重放调度,完全在预算之内。
用一次 POST /users/me/entries 创建周期性重放 —— schedule、command、expires_at。之后用 PATCH 静音;用 DELETE 退役;expires_at 自动替你退役。
限制以 Hoody Cron Managed Entries API 为准:标准 5 字段 cron 表达式加 @daily / @hourly 宏,分页每页最多 200 条,expires_at 可选,过了截止时间会自动禁用条目。
生产流量,录一次,按时间表重放。
重放 webhook 流量的常规工具 —— 录制器、重放服务、定时 mock。每一个都是 SaaS、sidecar 或你需要照看的脚本。hoody-files + hoody-cron 这一对都不是。
捕获周五的流量。安排下周的重放。等实验结束时,让 cron 条目自己过期。