當 n8n 工作流程處理數千個 API 請求時處理速率限制

你好
我正在建立一個 n8n 工作流程,用於處理大量記錄,並為每筆記錄發出 API 請求。它在較小批次中運作良好,但當數量增加時,我開始收到 429 Too Many Requests 回應。
我不想只是添加長時間的固定延遲,因為 API 根據端點有不同的速率限制。
我目前考慮的方案類似於:const retryAfter = $json.retryAfter || 2;
return [{
json: {
retryAfter,
nextAttempt: new Date(Date.now() + retryAfter * 1000).toISOString()
}
}];
在 n8n 中處理 API 速率限制的最佳生產方法是什麼?

描述問題/錯誤/問題

錯誤訊息是什麼(如有的話)?

請分享您的工作流程

(在畫布上選擇節點,使用鍵盤快捷鍵 CMD+C/CTRL+C 和 CMD+V/CTRL+V 來複製和貼上工作流程。)

分享最後一個節點返回的輸出

關於您的 n8n 設定的資訊

  • n8n 版本:
  • 資料庫(預設:SQLite):
  • n8n EXECUTIONS_PROCESS 設定(預設:own、main):
  • 執行 n8n 的方式(Docker、npm、n8n cloud、桌面應用程式):
  • 作業系統:

嘿 @Kabrooks,在你等待回覆的時候,這些東西可能對你有幫助:

建議的資源

自動符合你的問題。

文件:

論壇:

@Niffzy - 你之前幫助處理過類似的問題,能幫忙看一下嗎?

由 n8n 社群機器人自動建議。這是試用版 - 請在此分享意見反饋。

嗨 @Kabrooks 我會使用批處理、並發控制和指數退避的組合,而不是依賴固定延遲。

首先,限制 n8n 一次發送的請求數量。然後,當 API 返回 429 時,如果存在 Retry-After 標頭,請尊重它。

對於重試,使用類似這樣的方式:

const attempt = $json.attempt || 0;
const retryAfter = Number($json.retryAfter) || Math.pow(2, attempt);

return [{
json: {
...$json,
attempt: attempt + 1,
retryAfter
}
}];

我也會設定最大重試次數,並將重複失敗的請求移至單獨的錯誤/死信工作流程中。

重點是在 API 開始拒絕你之前控制請求速率,而不是試圖從數千個 429 錯誤中恢復。

@Kabrooks

既然您的 API 提供了明確的重試指示,您應該將 429 回應視為資料片段,而不是工作流失敗。

使用下列工作流結構:

  1. HTTP 請求節點:
    • 設定 > 錯誤時: 設定為 繼續(使用錯誤輸出)。這很關鍵;它可以防止工作流在出現 429 時停止。
  2. If 節點:
    • 檢查回應狀態是否為 429。
  3. 程式碼節點(「解析器」):
    • 如果是 429,提取 Retry-After 標頭。
    • 注意: 某些 API 會回傳秒數,其他則回傳時間戳記。您的程式碼應將其標準化為毫秒數。
const response = $json.error || $json; // 根據 n8n 如何回傳錯誤輸出而定
const retryAfterHeader = response.headers?.['retry-after'];

// 將標頭轉換為毫秒
let waitMs = 5000; // 預設備用值
if (retryAfterHeader) {
    // 如果標頭是數字(秒),轉換為毫秒。
    // 如果是日期字串,計算差異。
    waitMs = isNaN(retryAfterHeader) 
        ? new Date(retryAfterHeader).getTime() - Date.now() 
        : parseInt(retryAfterHeader) * 1000;
}

return {
    retry: true,
    waitMs: Math.max(waitMs, 1000), // 安全最小值 1 秒
    data: $json // 傳遞原始資料以進行重試
};
  1. 等待節點:
    • 將 等待時間 設定為運算式:{{ $json.waitMs }}。
  2. 循環回溯:
    • 將等待節點連接回 HTTP 請求 節點以重試特定記錄。

迴圈必須實施以下保障措施:

  • 最大重試次數: 在您的程式碼節點中,遞增 retryCount 屬性。如果 retryCount > 5,將項目路由到錯誤分支而不是再次循環。這可以防止無限循環消耗您的工作人員資源。
  • 死信佇列 (DLQ): 不要讓工作流簡單地「失敗」,而是將超過最大重試次數的項目路由到單獨的「錯誤處理」分支。此分支應將失敗記錄到資料庫(如 Supabase 或 Airtable)或發送 Slack 警告。這可讓您稍後手動檢查並僅重新執行失敗的記錄。

嗨 @Kabrooks 歡迎!
不同端點的限制是單獨控制每個節點的速度,而不是建立一個共享的重試路徑的理由。HTTP Request 節點在「新增選項」下有「批次處理」,包括「每批項目數」和「批次間隔」,文件將其描述為「迴圈項目加等待」的等效功能。作為每個節點的設定,呼叫嚴格端點的節點帶有自己的間隔,呼叫寬鬆端點的節點帶有另一個間隔,兩者都沒有周圍邏輯。
該節點設定中的「失敗時重試」會捕捉仍然遺漏的情況。其「重試間隔」是固定數字,而不是從回應讀取的任何內容,所以手動解析標頭只有在伺服器發送的值實際上在執行間變化時才值得其複雜性。