大家好,
我一直在測試 n8n 在工作流中途失敗時的行為,使用本機假 API 以便精確計算另一端發生的情況。自託管 n8n,使用 npx 執行,2026 年 11 月。
我的發現:
-
HTTP Request 節點發送 50 封電郵。第 33 個請求收到 503。節點失敗,但 49 封電郵已經傳遞。「使用原始工作流重試」會重新執行整個節點,因此 49 個客戶會收到兩次電郵(總共發送 99 封)。
-
同一工作流開啟「失敗時重試」(3 次嘗試):再次發送 99 封,49 個重複,執行顯示為成功。UI 中沒有任何內容告訴你有什麼問題。
-
運輸請求的逾時時間為 5 秒。API 實際上處理了它但在 10 秒後回覆。n8n 記錄失敗,重試再次發送(2 次運輸)。使用「失敗時重試」時它被處理了 3 次,最後仍然以錯誤結束。
-
公平地說:當 API 只是返回 503 並且不處理任何內容時,重試會從失敗的節點恢復,沒有重複。該情況工作正常。
我寫了一個小指令碼,在重新發送之前,詢問目標 API「這個項目是否已經處理過?」並只重新發送遺漏的項目。在情況 1 中,它只發送了 1 封遺漏的電郵(0 個重複)。但這取決於 API 是否有某種方式來查詢。
我的問題:
- 你在生產環境中遇到過像這樣的重複嗎?哪些節點/服務?
- 你今天如何處理:冪等密鑰、DB 檢查點表、每次執行分割為一個項目,還是乾脆接受?
- 對於不支援查詢或冪等性的服務,是否有任何真正有效的模式?
如果有人想重現,我很樂意分享測試設置。
您的两个示例暴露了不同的重试风险。在 n8n 2.46.6 中,「失败时重试」使用相同的执行输入再次调用节点。HTTP Request 节点在处理错误前会等待批次的请求结果。绿色重试告诉你最后一次尝试成功了,而不是早前的项目没有产生任何影响。
每次执行一个项目限制了影响范围,但仍然无法判断超时后是否发生了发货。检查点表可以保留那种不确定性:在发送前记录操作 ID,保持未知结果不自动重试,如果存在目标收据则根据它进行对账。既没有权威查询也没有目标幂等性保证的情况下,没有安全的自动规则既能避免重复又能保证交付。我不会将超时、滞后的「未找到」或单纯的 503 作为无写入的证明。
如果您分享合成设置和确切的 n8n 版本,我很感兴趣检查一个额外的情况:使用按项目错误输出,然后验证只有确认的无写入项目符合重放条件,而已提交但超时的项目保持未解决。
謝謝,這真的很有幫助。你表達得比我更清楚:綠色重試只是說明最後一次嘗試成功了。
設置在這裡:GitHub - parkseyoung1215-netizen/agent-recovery · GitHub
n8n 版本:2.46.6,透過 npx 自託管(與你提到的相同)。假 API 是 experiments/fake_shop.py,/scenario/N 在各種情況之間切換。
你提到的延遲「未找到」確實是我腳本中的一個真實漏洞。目前 recover.py 將負面查找視為安全重播,這正是你描述的情況。我會改變它,使得因逾時而失敗的項目保持未解決狀態,除非查找可信,我也會添加你的逐項錯誤輸出情況。我會在這裡發佈結果。
快速後續跟進結果。
我新增了你的案例:50 封郵件,customer10 收到 503(未寫入),customer20 已寫入但回覆在逾時後才到達。失敗的項目按項目處理,就像 n8n 的錯誤輸出一樣。
- 查詢立即反映寫入:兩個版本都只重新發送 customer10。0 個重複。
- 查詢滯後 8 秒於寫入:我的舊版本信任了早期的「未找到」並重新發送兩個,所以 1 個重複。新版本將兩個項目都保持「等待」狀態,在穩定期間後再檢查一次,然後只重新發送 customer10 並將 customer20 標記為已完成。0 個重複。
穩定期間仍然是對服務的假設,所以如果查詢滯後時間超過該期間,仍然有可能發生重複。沒有任何查詢的情況下,項目保持未解決狀態並轉交人工處理。
再次感謝,這發現了一個真實的錯誤。詳情在 repo 中(experiments/exp7_ambiguous_demo.py)。
感謝你發佈了測試用例和結果。我在 391324a 版本上對你的環回假商店執行了 recover.py。使用即時查詢時,原始的逾時電子郵件被找到,且有一次儲存的傳送。使用比結算視窗更長的查詢延遲時,真實的 CLI 計畫了重新傳送,假商店記錄了兩次傳送,但 CLI 仍然列印「0 duplicates」。該數字似乎是無條件列印的,所以我會將接受的重試請求與已驗證的傳送計數分開報告。
我也試了兩個格式不正確的查詢回應。HTTP 200 搭配 {} 進入了重新傳送集合;{"exists":"false"} 進入了已傳送集合。lookup() 可以通過返回 value if type(value) is bool else None 來保留第三種狀態。來自最終一致性查詢的明確 false 仍應表示「尚不可見」,即使在截止時間之後也是如此。使用截止時間來交由審核;只有目的地確認的無寫入或原始嘗試所尊重的冪等鍵應授權自動重放。我會保留的回歸是:一次確認的無寫入是可重放的,具有延遲或格式不正確的查詢的逾時寫入則不是。