分享方式:


處理 Azure Logic Apps 中的節流問題 (429 -「要求太多」錯誤)

適用於:Azure Logic Apps (使用量 + 標準)

如果您的邏輯應用程式工作流程遇到節流 (當要求數目超過目的地在特定時間內可處理的量時就會發生這種情況),會收到「HTTP 429 要求太多」錯誤。 節流可能造成資料處理延遲、效能速度降低等問題,以及導致超過指定重試原則等錯誤。

例如,使用量工作流程中的下列 SQL Server 動作會顯示 429 錯誤,該錯誤報告了節流問題:

Screenshot showing a Consumption workflow with a SQL Server action that has a 429 error.

下列各節說明工作流程可能會遇到的節流常見層級:

邏輯應用程式資源節流

Azure Logic Apps 具有自身的輸送量限制。 如果邏輯應用程式資源超過這些限制,則邏輯應用程式資源就會開始節流,而不僅是特定工作流程執行個體或執行。

若要在此層級尋找節流事件,請遵循下列步驟:

  1. Azure 入口網站中,開啟您的邏輯應用程式資源。

  2. 在邏輯應用程式資源的功能表上,選取 [監視] 底下的 [計量]

  3. 在 [圖表標題] 底下選取 [新增計量],以將另一個計量列新增至圖表。

  4. 在第一個計量列中,從 [計量] 清單選取 [動作節流處理事件]。 從 [彙總] 清單中,選取 [計數]

  5. 在第二個計量列中,從 [計量] 清單選取 [觸發程序節流處理事件]。 從 [彙總] 清單中,選取 [計數]

現在,圖表會顯示邏輯應用程式工作流程中動作和觸發程序的節流事件。 如需詳細資訊,請參閱在 Azure Logic Apps 中檢視工作流程健康情況和效能的計量

若要處理此層級的節流,可採用下列做法:

  • 限制可同時執行的工作流程執行個體數目。

    根據預設,如果工作流程的觸發條件在同時間多次符合,則該觸發程序的多個執行個體就會同時引發並同時執行,或「平行」執行。 每個觸發程序執行個體都會在先前作用中的工作流程執行個體執行完成之前引發。

    雖然可以同時執行的觸發程序執行個體預設數目無上限,但您可以開啟觸發程序的並行設定以限制此數目,並視需要選取預設值以外的限制。

  • 啟用高輸送量模式。

  • 停用觸發程序中的陣列取消批次處理或「分割」行為。

    如果觸發程序傳回要處理的其餘工作流程動作陣列,則該觸發程序的分割設定會分割陣列項目,並為每個陣列項目啟動工作流程執行個體。 此行為有效觸發多個並存執行,直到分割上限

    若要控制節流,請關閉觸發程序的分割行為,並讓工作流程使用單一呼叫處理整個陣列,而不是處理每個呼叫的單一項目。

  • 將動作重構為多個較小的工作流程。

    如先前所述,使用量邏輯應用程式工作流程限制為可在 5 分鐘期間內執行的預設動作數目。 雖然您可以藉由啟用高輸送量模式增加此限制,但或許可以考慮將工作流程的動作分成更小的工作流程,讓每個工作流程中執行的動作數目維持在限制以下。 如此一來,即可降低單一工作流程的負擔,並將負載分散到多個工作流程。 這個解決方案較適合用於處理大型資料集的動作或加速許多同時執行的動作、迴圈反覆項目,或每個迴圈反覆項目內超過動作執行限制的動作。

    例如,下列使用量工作流程會執行所有工作,以便從 SQL Server 資料庫取得資料表,並從每個資料表取得資料列。 For each 迴圈會同時查看每個資料表,讓取得資料列動作傳回每個資料表的資料列。 依據這些資料表中的資料量,這些動作可能會超過動作執行的限制。

    Screenshot showing Consumption workflow

    重構之後,原始工作流程會分割成父代工作流程和子系工作流程。

    下列父代工作流程會從 SQL Server 取得資料表,然後呼叫每個資料表的子系工作流程以取得資料列:

    Screenshot showing Consumption parent workflow that gets the SQL Server tables and calls the child workflow.

    父代工作流程會呼叫下列子系工作流程,以取得每個資料表的資料列:

    Screenshot showing Consumption child workflow that gets the rows for each table.

連接器節流

每個連接器都有本身的節流限制,您可以在每個連接器的技術參考頁面上找到相關資訊。 例如,Azure 服務匯流排連接器的節流限制允許每分鐘最多 6,000 次呼叫,而 SQL Server 連接器的節流限制會根據作業類型而有所不同

部分觸發程序和動作 (例如 HTTP) 有「重試原則」,您可以根據重試原則限制自訂原則,以實作例外狀況處理。 此原則會指定若原始要求逾時或失敗,並傳回 408、429 或 5xx 回應,觸發程序或動作是否要重試要求,以及重試頻率為何; 這樣一來,當節流開始並傳回 429 錯誤,Logic Apps 就會遵循支援的重試原則。

如要了解觸發程序或動作是否支援重試原則,請查看觸發程序或動作的設定。 若要檢視觸發程序或動作的重試嘗試,請前往邏輯應用程式的執行歷程記錄,選取想要檢閱的流程執行,然後展開該觸發程序或動作,以檢視輸入、輸出和任何重試的詳細資料。

下列使用量工作流程範例顯示您可以在其中找到 HTTP 動作的這項資訊:

Screenshot showing Consumption workflow with an HTTP action's run history, retries, inputs, and outputs.

雖然重試歷程記錄會提供錯誤資訊,但您或許依然會難以區分連接器節流與目的地節流。 在這種情況下,您可能必須檢閱回應的詳細資料或執行節流間隔計算以識別來源。

對於多租用戶 Azure Logic Apps 中的使用量邏輯應用程式工作流程,節流會在「連線」層級發生。 對於在整合服務環境 (ISE) 中執行的邏輯應用程式工作流程,由於非 ISE 連線是在多租用戶 Azure Logic Apps 中執行,因此仍會發生節流。 不過,ISE 連接器所建立的 ISE 連線會在您的 ISE 中執行,因此不會發生節流。

若要處理此層級的節流,可採用下列做法:

  • 為單一動作設定多個連線,讓工作流程可分割資料以便處理。

    請考慮您是否能將動作的要求分割至多個有相同目的地 (使用相同認證) 的連線,以分散工作負載。

    例如,假設工作流程從 SQL Server 資料庫取得資料表,然後從每個資料表取得資料列。 您可以根據必須處理的資料列數目,使用多個連線和多個 For each 迴圈,將資料列總數分割成較小的集合進行處理。 此案例會使用兩個 For each 迴圈將資料列總數分割為兩半。 第一個 For each 迴圈使用取得前半部的運算式, 另一個 For each 迴圈使用其他運算式取得後半部,例如:

    • 運算式 1:用 take() 函式取得集合的前端。 如需詳細資訊,請參閱 take() 函式

      @take(collection-or-array-name, div(length(collection-or-array-name), 2))

    • 運算式 2:用 skip() 函式移除集合的前端,並傳回所有其他項目。 如需詳細資訊,請參閱 skip() 函式

      @skip(collection-or-array-name, div(length(collection-or-array-name), 2))

      下列使用量工作流程範例示範如何使用這些運算式:

      Screenshot showing a Consumption workflow that uses multiple connections for a single action.

  • 為每個動作設定不同連線。

    請考慮即使動作連線到相同服務或系統且使用同樣的認證,您是否也能將每個動作的要求分佈到其連線,以分散工作負載。

    例如,假設工作流程從 SQL Server 資料庫取得資料表,然後從每個資料表取得各個資料列。 您可以在此使用不同連線,也就是透過一個連線取得資料表,透過另一個連線取得每個資料列。

    下列範例顯示使用量工作流程可針對每個動作建立和使用不同的連線:

    Screenshot showing a Consumption workflow that creates and uses a different connection for each action.

  • 變更 "For each"迴圈上的並行或平行處理原則。

    根據預設,"For each" 迴圈反覆項目會同時執行至並行上限。 如果您的連線在 "For each" 迴圈內發生節流,則可以減少平行執行的迴圈反覆項目數量。 如需詳細資訊,請參閱下列文件:

目的地服務或系統節流

連接器有自己的節流限制,連接器所呼叫的目的地服務或系統也可能有節流限制。 例如,Microsoft Exchange Server 中部分 API 的節流限制比 Office 365 Outlook 連接器更嚴格。

根據預設,邏輯應用程式的工作流程執行個體和這些執行個體內的任何迴圈或分支,都會「平行」執行。 這種行為代表多個執行個體可以同時呼叫相同的端點。 每個執行個體都不知道其他執行個體的存在,因此嘗試重試失敗的動作可建立競爭條件 (英文),讓多個呼叫嘗試同時執行,但唯有在節流開始前抵達目的地服務或系統的呼叫才會成功。

例如,假設您有一個包含 100 個項目的陣列, 您可以使用 "For each" 迴圈逐一查看陣列,並開啟迴圈的並行控制,以便將平行反覆項目的數目限制為 20 或目前的預設限制。 在該迴圈內,動作會將陣列中的項目插入每秒只允許 15 次呼叫的 SQL Server 資料庫, 這會導致重試的待處理項目 (backlog) 不斷累積且一直無法執行,因而引發節流問題。

下表描述當動作的重試間隔為 1 秒時,迴圈中發生情況的時間軸:

時間點 執行的動作數目 失敗的動作數目 等候的重試次數
T + 0 秒 20 次插入 因 SQL 限制導致 5 次失敗 5 次重試
T + 0.5 秒 15 次插入,因為前 5 次重試還在等候 15 次全部失敗,因為先前的 SQL 限制對於多出的 0.5 秒仍然有效 20 次重試
(先前 5 次 + 新的 15 次)
T + 1 秒 20 次插入 5 次失敗加上先前的 20 次重試 (因為有 SQL 限制) 25 次重試 (先前 20 次 + 新的 5 次)

若要處理此層級的節流,可採用下列做法:

  • 建立個別工作流程,讓每個工作流程處理單一作業。

    • 繼續以本節的 SQL Server 案例為例,您可以建立一個將陣列項目放入佇列的工作流程,例如 Azure 服務匯流排佇列。 接著建立另一個工作流程,只對該佇列中每個項目執行插入作業。 如此一來,任何特定時間都只有一個工作流程執行個體在執行,若不是完成插入作業並繼續處理佇列中的下一個項目,就是執行個體收到 429 錯誤,但不會嘗試進行沒有效率的重試。

    • 建立父代工作流程,為每個動作呼叫子系或巢狀工作流程。 如果父代必須根據其結果呼叫不同的子系工作流程,您可以使用條件動作或切換動作決定要呼叫的子系工作流程。 此模式有助於減少呼叫或作業數目。

      例如,假設您有兩個工作流程,每個工作流程都有輪詢觸發程序會每分鐘檢查您的電子郵件帳戶是否有特定主旨,例如「成功」或「失敗」。 這個設定每小時會產生 120 個呼叫。 若您改為建立每分鐘輪詢的單一父代工作流程,並根據主旨為「成功」或「失敗」呼叫要執行的子系工作流程,就能將此案例中的輪詢檢查數目減半為 60。

  • 設定批次處理。 (僅限使用量工作流程)

    如果目的地服務支援批次作業,您便能以群組或批次方式處理項目並解決節流問題,而不必個別處理項目。 若要實作批次處理解決方案,請建立「批次接收者」邏輯應用程式工作流程和「批次傳送者」邏輯應用程式工作流程。 批次傳送者會收集訊息或項目,直到符合您指定的標準,然後將這些訊息或項目傳送到單一群組中。 批次接收者會接受該群組並處理這些訊息或項目。 如需詳細資訊,請參閱以群組方式批次處理訊息

  • 使用觸發程序和動作的 Webhook 版本,而不是輪詢版本。

    為什麼? 輪詢觸發程序會持續按照特定間隔檢查目的地服務或系統, 如果間隔非常短 (如每秒),就可能會發生節流問題。 相較之下,HTTP Webhook 等 Webhook 觸發程序或動作只會在訂閱時間對目的地服務或系統建立單一呼叫,且僅要求目的地在事件發生時通知觸發程序或動作。 如此一來,觸發程序或動作就不需要持續檢查目的地。

    因此,如果目的地服務或系統支援 Webhook 或提供具有 Webhook 版本的連接器,則此選項會比使用輪詢版本好。 識別 Webhook 觸發程序和動作時,請確認具有 ApiConnectionWebhook 類型,或其無需您指定週期。 如需詳細資訊,請參閱 APIConnectionWebhook 觸發程序APIConnectionWebhook 動作

下一步