沉默的 API 杀手:缓存如何破坏了我的集成以及我如何修复它
发布: (2026年4月4日 GMT+8 02:39)
3 分钟阅读
原文: Dev.to
Source: Dev.to
Problem
我最近花了两天时间在一次机器对机器的 API 集成中追踪一个“幽灵”。该集成在 staging 环境下运行完美,但在生产环境中,我们的 webhook 接口偶尔未能确认来自关键第三方服务的回执,导致重复处理和事件丢失。第三方日志显示我们的端点返回了 200 OK,而我们的日志却显示相应的后台任务根本没有运行。问题是间歇性的,且本地无法复现——这正是状态或环境问题的典型征兆。
Root Cause
经过大量日志排查后,我发现我们的生产 API 网关(我们无法控制的层)对 POST 请求进行了激进的缓存。由于我们的幂等键(idempotency‑key)在一段时间内是静态的(出于业务逻辑需要将事件分组),网关在这些相同的 POST 请求到达应用服务器之前,就直接返回了缓存的 200 响应。我们的应用根本没有看到请求,因此任务从未入队。网关返回的“健康” 200 响应掩盖了业务逻辑的彻底失败。
Fix
- 添加缓存指令 – 我们在该 webhook 接口上添加了
Cache-Control: no-store头部,指示所有中间缓存跳过存储。 - 修改幂等策略 – 我们重新设计了幂等键的生成方式,使其对每个事件都是真正唯一的,确保每个请求都是不同的,从而不可被缓存。
Takeaways
- 必须在每个代理、CDN 或网关层验证缓存行为,尤其是非 GET 请求。
- 来自下游缓存的成功 HTTP 状态码可能是致命的假象。
- 在 API 设计中应把缓存头视为一等公民;你认为是 “GET” 操作的请求,网络可能会把它解释为 “可缓存” 操作,而这种假设会悄无声息地破坏系统。