已验证2026年7月24日4 分钟阅读

n8n 的 POST 超时后直接重试会发生什么?40 次写入对照

服务先写入、响应再超时的 40 次对照中,无幂等键重试恢复了 20/20 个瞬时故障,却产生 30 条重复记录;服务端执行幂等后,同样恢复 20/20,重复为 0。

PUBLIC EVIDENCE PACKAGE

不要只读结论,下载原始记录。

成功状态藏住了 30 条重复记录

两条重试分支都恢复了 20/20 个瞬时超时。从 n8n 执行列表看,它们没有区别,最后都是 success。

HTTP 服务保存的记录却不同。没有幂等键的分支提交了 50 条记录,其中 30 条是重复写入;带键且由服务端执行幂等的分支只提交 20 条,每次业务操作一条。成功率相同,数据结果完全不同。

这次测试处理的是一个具体故障:服务端已经完成写入,但响应在返回 n8n 前超时。客户端看到 timeout,无法据此判断写入是否发生。若下一步只是把 Retry On Fail 打开,同一次业务操作可能被服务器执行多次。

三条分支请求同一个写入接口

实验固定使用 n8n 2.30.5。每次工作流同时运行三条 POST 分支:不重试且不带键、最多三次请求且不带键、最多三次请求并携带 Idempotency-Key。请求超时为 300 ms,重试等待为 100 ms。

本地 HTTP 服务在收到请求时先创建记录,再决定是否把响应延迟 800 ms。延迟超过客户端超时,但不会撤销已经创建的记录。带键分支有额外规则:相同键再次到达时,服务返回第一次创建的 recordId,不再创建新记录。

场景重复次数工作流运行
立即返回 2001010
第一次写入后响应超时1010
前两次写入后响应超时1010
每次写入后响应都超时1010

40 次工作流产生 120 个策略观察。夹具共收到 220 个 HTTP 请求,保存 170 条记录。所有请求、记录、节点耗时和输出哈希都在证据包中。

瞬时超时:恢复相同,副作用不同

策略恢复的瞬时超时提交记录重复记录
三次请求,无键20 / 205030
三次请求,服务端执行幂等20 / 20200

第一次响应超时时,无键分支发出两次请求,也创建两条记录。前两次响应都超时时,它发出三次请求,创建三条记录。n8n 最终拿到 200,只能说明最后一次请求收到了成功响应,不能证明前面的超时请求没有落库。

带键分支也分别发出两次和三次请求。区别发生在接收端:第二、第三次请求命中第一次操作的键,返回同一个 recordId。幂等不是少发请求,而是重复请求到达时不重复执行副作用。

不重试也会得到一个危险的失败状态

三个超时场景里,不重试分支有 30/30 次显示 failure。HTTP 服务同时保留了 30 条已经提交的记录。

所以失败状态也不能直接触发“重新创建”。这时业务结果是未知,而不是确定失败。生产流程需要保存业务操作 ID、请求 ID和工作流执行 ID,再通过供应商的查询接口或对账任务确认结果。没有查询入口的写入接口,本身就不适合在超时后自动重放。

持续超时没有被重试修好

每次响应都延迟时,两条重试分支均 10/10 失败。无键分支为十次业务操作创建了 30 条记录,其中 20 条重复;带键分支创建 10 条,没有重复。

幂等键限制了副作用,没有把不可用服务变成可用服务。达到尝试上限后,流程仍要进入未知结果队列,等待状态查询、对账或人工处理。把执行标成 success 会掩盖故障,把它当作可以无限重试也会继续消耗请求配额。

只有接收端执行,Idempotency-Key 才有用

本实验的服务端保存键与首次结果,后续相同键返回原 recordId。若对方 API 忽略这个请求头,n8n 填入一个随机字符串不会产生任何保护。

不同供应商的协议也不能互相套用。Stripe 的官方说明会保存首次请求的状态码和响应体,并限制键的保留时间与参数复用;其他 API 可能采用不同的冲突、过期和失败缓存规则。上线前要核对接收端文档,而不是只看请求头名称。

键应该代表一次业务操作,并在该操作的所有重试中保持不变。重新生成键等于告诉服务端这是一次新操作。相同键配不同参数也需要明确处理,否则会把调用方错误藏在去重逻辑里。

第一次全量运行为什么没有进入结论

第一次 40 次运行有两个策略观察没有通过冻结协议。在“前两次响应超时”的第一轮,两条重试分支只向夹具发出两次请求便失败,之后九轮正常。该批数据被标记为 FAILED_VALIDATION 并归档,没有从 CSV 中删除异常行。

随后只复跑该场景十次,30 个策略观察全部匹配。第二次从全新容器执行完整 40 次,120 个观察的结果、请求数和记录数均与协议一致,才生成当前证据包。

我们没有把第一次偏差解释成 n8n 缺陷。现有记录只能确认那次 CLI 运行没有完成预期的第三次请求,不能区分资源抖动、任务运行器或其他瞬时原因。它提醒我们:采集器必须检查实际请求数,不能只按配置推定“最多三次”已经发生。

我会怎样配置生产写入

先查接收端是否有正式的幂等协议和状态查询接口。支持时,用内部业务操作 ID派生稳定键,同一操作的重试复用该键,并保存返回的资源 ID。参数改变就生成新的业务操作,不偷用旧键。

超时结果进入 unknown 状态。流程先查询或对账,再决定是否补发。只有确认没有副作用,或接收端能按键去重时,才允许自动重试写入。

监控至少同时记录四件事:工作流执行 ID、业务操作 ID、供应商请求 ID和最终资源 ID。单看 n8n 的 success/failure,无法发现本实验中的 30 条重复记录。

这组数字不能证明什么

  • 本地服务按确定规则运行,没有模拟公网抖动、并发客户端或供应商限流;
  • 没有测试支付、消息发送、库存扣减等具体业务;
  • 没有测试键过期、相同键参数冲突和并发中的首次请求;
  • 没有证明所有服务都接受 Idempotency-Key;
  • 十次重复用于验证固定协议,不用于估算生产超时概率。

workflow.json 可以导入 n8n 2.30.5。runs.csv 保存 120 个策略观察;requests.csv 记录 220 个请求;records.csv 是 170 条服务端提交记录。复跑时应使用新的输出目录,不覆盖这批结果。

来源与核验日期

  1. AI Brief Note 原始实验摘要:40 次工作流、120 个策略观察、请求数、提交记录、重复记录和限制。 · 已核验 · generated_from_40_workflow_runs_2026-07-24
  2. n8n 官方 HTTP Request 节点文档:请求方法、请求头、超时和节点配置。 · 已核验 · official_site_checked_2026-07-24
  3. IETF HTTPAPI 工作组草案:Idempotency-Key 请求头用于让 POST、PATCH 等非幂等方法具备容错重放协议。 · 已核验 · ietf_datatracker_checked_2026-07-24
  4. Stripe 官方 API 文档:其幂等键保存、参数比较和过期规则,作为供应商协议差异的实例。 · 已核验 · official_site_checked_2026-07-24