重試非同步函式

本文說明如何提出非同步 (非 HTTPS) 請求 背景函式,以便在失敗時重試。

重試的語意

Cloud Functions 可針對事件導向函式提供至少一次執行作業 針對事件來源所發送的每一個事件套用適當設定。根據預設 因錯誤而終止,此時不會再次叫用此函式 系統就會捨棄事件在事件導向上啟用重試時 函式,Cloud Functions 會重試失敗的函式叫用,直到 或重試期過期。

對於第 2 代函式 重試期會在 24 小時後失效。第 1 代函式的有效期限為 。 Cloud Functions 會使用 指數輪詢策略,持續增加到 10 之間 和 600 秒 這項政策適用於新函式 從頭部署容器但不會溯及既往,亦不會溯及既往 執行首次部署的函式,並用於上述變更 這份版本資訊 結果。

如果函式並未啟用重試功能 (預設值), 一律會回報執行成功,且 200 OK 回應代碼 出現在記錄檔中即使函式發生錯誤也是如此。目的地: 明確指出函式發生錯誤時 回報錯誤 才是正確的做法

事件導向函式為何無法完成

在極少數情況下,函式可能會因內部錯誤而提早結束,根據預設,函式可能會也可能不會自動重試。

事件導向函式可能因為 傳回在函式程式碼本身擲回的錯誤。這可能是因為 包括:

  • 函式包含錯誤且執行階段擲回例外狀況。
  • 函式無法連至服務端點,或在嘗試連線時逾時 。
  • 函式刻意擲回例外狀況 (例如: 驗證失敗)。
  • Node.js 函式傳回遭拒的承諾,或將非 null 值傳遞至 回呼。

在上述任何情況下,函式皆預設停止執行,而事件 就會遭到捨棄如要在發生錯誤時重試函式,您可以 並變更預設重試政策 設定「失敗時重試」資源。 如此即會重複重試事件,直到 函式順利完成,或是重試逾時期限已過。

啟用或停用重試

透過控制台設定重試

如果您要建立新的函式:

  1. 「Create Function」畫面, 在「觸發條件」下方,選擇要做為觸發條件的事件類型 函式。
  2. 勾選「失敗時重試」核取方塊以啟用重試。

如要更新現有函式:

  1. 在「Cloud Functions 總覽」頁面中,按一下 您要更新的函式,開啟其「函式詳細資料」畫面,然後 在選單列中選擇「編輯」,即可顯示「觸發條件」窗格。
  2. 選取或取消勾選「失敗時重試」核取方塊,即可啟用或停用 重試。

透過函式程式碼設定重試作業

使用 Cloud Functions for Firebase 時 函式。對背景函式 (如 functions.foo.onBar(myHandler);,使用 runWith 並設定失敗政策:

functions.runWith({failurePolicy: true}).foo.onBar(myHandler);

如果按上述方式設定 true,則可設定函式在失敗時重試。

最佳做法

本節將說明使用重試的最佳做法。

使用重試來處理暫時性錯誤

因為您的函式會持續重試,直到成功執行為止, 應該透過測試,避免程式碼中出現錯誤等永久性錯誤 再啟用重試功能重試最適合處理間歇性或暫時性 重試時極可能解決的結果,例如: 不穩定的服務端點或逾時。

設定結束條件以避免無限的重試循環

在下列情況下,最佳做法是保護函式,避免發生連續迴圈: 重試方法很簡單,只要加入定義明確的結束條件即可 ,然後再開始處理。請注意,只有在下列情況中 您的函式已成功啟動,並且能夠評估結束條件。

有一個簡單又有效的方法,就是捨棄時間戳記早於 系統設定在特定時間範圍內這有助於避免在失敗時,避免過度執行 將時間安排在持續性或 比預期更長的時間

例如,下面的程式碼片段會捨棄 10 秒之前的所有事件:

const eventAgeMs = Date.now() - Date.parse(event.timestamp);
const eventMaxAgeMs = 10000;
if (eventAgeMs > eventMaxAgeMs) {
  console.log(`Dropping event ${event} with age[ms]: ${eventAgeMs}`);
  callback();
  return;
}

catch 與 Promise 搭配使用

如果您的函式已啟用重試功能,任何未處理的錯誤都會觸發重試。 並確認程式碼會擷取不應導致重試的所有錯誤。

以下是正確做法的範例:

return doFooAsync().catch((err) => {
    if (isFatal(err)) {
        console.error(`Fatal error ${err}`);
    }
    return Promise.reject(err);
});

將可重試的事件導向函式設為冪等

可重試的事件驅動函式必須為冪等。以下是一些 使此類函式成為冪等的一般準則:

  • 許多外部 API (例如 Stripe) 都可讓您提供冪等鍵 做為參數如果您使用的是這類 API,則應將事件 ID 做為 冪等鍵
  • 冪等性適用於至少傳送一次的提交內容,因為這樣可以確保 重試。所以撰寫可靠程式碼的一般最佳做法是 與重試的冪等性
  • 請確保您的程式碼為內部冪等。例如:
    • 確保在不變更 結果。
    • 在變更狀態之前,查詢交易中的資料庫狀態。
    • 確保所有連帶影響本身也是冪等的。
  • 在函式外強制執行交易檢查,與程式碼無關。 例如,將特定事件 ID 已有記錄的狀態保留於某個位置,
  • 請在頻外處理重複的函式呼叫。舉例來說 程序會在重複的函式呼叫後進行清除。

設定重試政策

根據您的 Cloud 函式需求,您可能會想設定 重試政策。這樣您就能任意組合 包括:

  • 請將重試期從 7 天縮短至 10 分鐘。
  • 變更指數輪詢的輪詢時間下限和上限 重試策略。
  • 請變更重試策略以立即重試。
  • 設定 無效信件主題
  • 設定傳送嘗試次數上限和下限。

設定重試政策的步驟如下:

  1. 編寫 HTTP 函式。
  2. 使用 Pub/Sub API 建立 Pub/Sub 訂閱項目,並指定以下項目的網址: 做為目標

請參閱 Pub/Sub 說明文件,瞭解如何處理失敗問題 ,進一步瞭解如何直接設定 Pub/Sub。