啟用事件導向函式重試功能
本文說明如何為事件導向函式啟用重試功能。自動重試功能不適用於 HTTP 函式。
事件導向函式無法完成的原因
在極少數情況下,函式可能會因內部錯誤而提早結束,根據預設,函式可能會也可能不會自動重試。
更常見的情況是,事件導向函式可能會因函式程式碼本身擲回的錯誤,而無法順利完成。可能原因包括:
- 函式包含錯誤且執行階段擲回例外狀況。
- 函式無法連線至服務端點,或在嘗試連線時逾時。
- 函式刻意擲回例外狀況 (例如,當參數驗證失敗時)。
- Node.js 函式傳回遭拒絕的 promise,或將非
null值傳遞至回呼。
在上述任一情況下,函式都會停止執行並傳回錯誤。對於事件觸發條件所產生的訊息,系統設有重試政策 (Retry policies),您可根據函式需求進行自訂。
重試的元件資訊
Cloud Run functions 會針對事件來源發出的每個事件,至少執行一次事件導向函式。重試政策的設定方式取決於您如何建立函式:
- 透過Google Cloud 控制台或 Cloud Run Admin API 建立的函式需另行建立並管理事件觸發條件。觸發條件會有預設的重試行為,可根據函式需求加以自訂。
- 使用 Cloud Functions 第 2 代 API 建立的函式會間接建立必要的事件觸發條件,例如 Pub/Sub 主題或 Eventarc 觸發條件。根據預設,系統會停用這些觸發條件的重試機制,您可以使用 Cloud Functions v2 API 重新啟用。
使用 Cloud Run 建立的事件驅動函式
透過 Google Cloud 控制台或 Cloud Run Admin API 建立的函式需另行建立並管理事件觸發條件。強烈建議檢閱各類型觸發條件的預設行為:
- Eventarc 重試政策的預設訊息保留時間為 24 小時,並採用指數輪詢延遲。請參閱 Eventarc 說明文件中的重試事件。
- Pub/Sub 預設會對所有訂閱項目使用立即重新傳送政策。請參閱 Pub/Sub 說明文件,瞭解如何處理訊息傳送失敗和重試要求。
使用 Cloud Functions 第 2 代 API 建立的事件驅動函式
使用 Cloud Functions 第 2 代 API 建立的函式 (例如使用 Cloud Functions gcloud CLI、REST API 或 Terraform),會自動為您建立並管理事件觸發條件。根據預設,如果函式叫用作業因錯誤而終止,系統不會再次叫用函式,而且會捨棄事件。為事件導向函式啟用重試功能後,任何在 Cloud Run functions 中失敗的函式叫用作業,都會重新嘗試至作業順利完成或超過重試期限為止。
如果函式未啟用重試功能 (預設為停用),函式一律會回報執行成功,且記錄檔中可能會顯示 200 OK 回應代碼。即使函式發生錯誤,也會發生這種情況。為清楚說明函式何時發生錯誤,請務必妥善回報錯誤。
啟用或停用重試功能
您可以使用 Google Cloud CLI 來啟用或停用重試功能。根據預設,系統會停用重試功能。
透過 Google Cloud CLI 設定重試
如要透過 Google Cloud CLI 啟用重試功能,請在部署函式時加入 --retry 旗標:
gcloud functions deploy FUNCTION_NAME --retry FLAGS...
如要停用重試功能,請重新部署函式,但不要加入 --retry 旗標:
gcloud functions deploy FUNCTION_NAME FLAGS...
重試時間範圍
這個重試時間範圍會在 24 小時後到期。Cloud Run functions 會使用指數輪詢策略重試新建立的事件導向函式,輪詢時間會逐漸增加,介於 10 到 600 秒之間。最佳做法
本節將說明使用重試的最佳做法。
使用重試來處理暫時性錯誤
由於您的函式會不斷重試,直到執行作業成功為止,因此應該先透過測試消除像是程式設計錯誤這一類的永久性錯誤,然後再啟用重試。重試最適合用來處理經過重試之後極有可能解決的間歇性或暫時性失敗,例如不穩定的服務端點或逾時。
設定結束條件以避免無限的重試循環
使用重試時,最佳做法是避免函式不斷循環。您可以在函式開始處理「之前」,加入妥善定義的結束條件來達成此目標。請注意,只有在函式順利啟動並能評估結束條件時,這項技術才能發揮作用。
有一個簡單有效的方法,就是捨棄時間戳記早於某特定時間的事件。針對永久性或失敗時間比預期時間長的情況,這樣做有助於避免過度執行。
例如,下方程式碼片段會捨棄 10 秒之前的所有事件:
Node.js
Python
Go
Java
C#
Ruby
PHP
區分可重試的函式和嚴重錯誤
如果您的函式已啟用重試,那麼所有未處理的錯誤都會觸發重試。請確保程式碼會擷取不應導致重試的任何錯誤。
Node.js
Python
Go
Java
C#
Ruby
PHP
將可重試的事件導向函式設為冪等結構
可重試的事件導向函式必須是冪等函式。以下是將這類函式設定為冪等的一些通則:
- 許多外部 API (例如 Stripe) 都可讓您提供冪等鍵做為參數。如果您使用此類 API,應使用事件 ID 做為冪等鍵。
- 冪等可以與至少一次的執行完美搭配使用,因為冪等可以使重試安全執行。因此,編寫可信賴程式碼的一般最佳做法是將冪等與重試結合使用。
- 請確保您的程式碼為內部冪等,例如:
- 確保異動可以發生多次,也不會變更結果。
- 在變更狀態之前,查詢交易中的資料庫狀態。
- 確保所有連帶影響本身也是冪等的。
- 在函式外強制執行交易檢查,不受程式碼影響。 例如,將已處理的特定事件 ID 保持於在某處記錄的狀態。
- 請在頻外處理重複的函式呼叫。比方說,發生重複函式呼叫後,使用單獨的清除程序清除所用資源。
設定重試政策
視 Cloud Run 函式需求而定,您可考慮直接設定重試政策,如此就能設定下列任意組合:
- 將重試期限從 7 天縮短至 10 分鐘。
- 變更指數輪詢重試策略的最短和最長輪詢時間。
- 將重試策略變更為立即重試。
- 設定 dead-letter 主題。
- 設定傳送嘗試次數上限和下限。
如要設定重試政策,請按照下列步驟操作:
- 編寫 HTTP 函式。
- 使用 Pub/Sub API 建立 Pub/Sub 訂閱項目,將函式的網址指定為目標。
想進一步瞭解如何直接設定 Pub/Sub,請參閱 Pub/Sub 說明文件中的失敗處理方式。