Checkly 用 Claude Code 重写日均 9200 万消息的生产服务
监控平台 Checkly 让 Claude Code 把日处理 9200 万消息的 Node.js 后台服务 Resul…
监控与可观测性平台 Checkly 近日公开了一项工程实验:让 Anthropic 的 AI 编程助手 Claude Code 把公司核心后台组件 Results Daemon 从 Node.js 重写为 Go。该组件每天处理约 9200 万条消息(约 4000 万条检测结果 + WebSocket 推送),是公司高吞吐的关键路径之一。重写后服务以零事故上线,运行 Pod 数量减少约 70%,数据库负载也明显下降,Go 的强类型系统还在事后为 AI 生成的代码提供了回归保护。
为什么决定重写
Results Daemon 是一个后台 Worker,负责消费 Runner 产出的检测结果、写库、判定检查状态、触发告警、安排重试,并向 CLI 与 Web UI 推送实时更新。随着 Checkly 全平台检测量在过去一年翻倍,该组件开始成为瓶颈:频繁触发 on-call 告警,且由于是 vanilla JavaScript,类型安全薄弱,每次改动都难以快速安全地落地。团队最终决定用 Go 重写,并以「agentic engineering」的方式让 AI Agent 完成实际编码。
先建测试骨架,再让 Agent 写代码
Checkly 把这次实验的核心经验总结为一句话:在 Agent 落笔之前,必须由「人」先定义「正确性」。他们在重写启动前构建了一套黑盒测试框架,对系统输入与确定性输出做逐字节比对,并遵循几条设计原则:
- 测试框架与被测代码完全解耦,不绑定语言或实现。
- 每个测试用例都对应一份「golden file」,由旧系统先生成,重写后用于断言 byte-to-byte 一致性。
- UUID、时间戳等非确定字段在 golden file 中以
<uuid>、<timestamp>占位,但仍做类型校验,防止行为漂移。 - 把数据库、消息队列、缓存等周边依赖视为「边界」,由测试框架统一管理,被测系统只通过环境变量指向它们。
- 边界一律使用真实实例:数据库用真实 PostgreSQL 容器,SQS 类简单边界则自研仿真器,理由是比 ElasticMQ、LocalStack 更轻、更易断言。
承载这套骨架的技术选型包括 Playwright(黑盒模型契合,且 Checkly 自身合成监控就基于它)、Docker Compose(本地与 CI 一致启停容器)、Toxiproxy(用于模拟网络故障下的行为)。
用真实业务数据生成测试输入
Results Daemon 的输出由两类输入决定:检查结果(Failed / Degraded / Success 等状态及元数据)以及结果到达时刻的检查配置(重试规则、告警规则等)。Checkly 由此得出第二条原则——行为覆盖率正比于输入的多样性,覆盖所有「账号配置 × 组配置 × 检查配置 × 结果状态」的组合,理论上即可覆盖全部代码路径。
他们从内部数据湖抽取了过去 24 小时(Checkly 最长的检查调度周期)的全部账号、组、检查配置与结果状态,灌入 ClickHouse 后按唯一配置和结果做「折叠」并标注出现频次,再用这些真实分布去播种测试场景,绑死业务规则(例如重派任务在 Job 未指定运行时长时取自账号配置)。
最终通过代码覆盖率报告评估骨架有效性,目标覆盖率为 90%–100%,覆盖率结果还会回传给 Agent 供其继续审视遗漏分支。
实际收益与可复用经验
- 上线后零事故,Pod 数减少约 70%,数据库压力下降。
- Go 的类型系统为 AI 生成的代码加了一层防护,事后修改与迭代更安全。
- 「测试先行 + golden file + 真实边界」这套方法论不限于这次重写,可复用于其他遗留服务的 Agent 重构。
对考虑把 AI Agent 引入关键生产代码的团队而言,Checkly 的案例给出了一条相对克制的路径:先把「什么算正确」以机器可验证的方式定义清楚,再放手让 Agent 写实现,并辅以高覆盖率的真实业务输入与逐字节比对——这比直接让 Agent 自由发挥更适合高吞吐生产环境。
