本文說明如何為事件驅動的 Cloud Run 函式啟用重試功能。自動重試功能不適用於 HTTP 函式。
事件導向函式無法完成的原因
在極少數情況下,函式可能會因內部錯誤而提早結束,根據預設,函式可能會也可能不會自動重試。
更常見的是,事件驅動函式可能會因函式程式碼本身擲回的錯誤而無法順利完成。發生這種情況的原因可能包括:
- 函式包含錯誤且執行階段擲回例外狀況。
- 函式無法連上服務端點,或在嘗試連線時逾時。
- 這個函式會刻意擲回例外狀況 (例如,當參數驗證失敗時)。
- Node.js 函式會傳回已遭拒絕的承諾,或將非
null
值傳遞至回呼。
在上述任何情況下,函式都會停止執行並傳回錯誤。產生訊息的事件觸發事件具有重試政策,您可以自訂這些政策,以滿足函式的需求。
重試的語意
Cloud Run 函式會為事件來源發出的每個事件,提供至少一次的事件導向函式執行作業。重試的設定方式取決於您建立函式的做法:
- 在 Google Cloud 控制台或透過 Cloud Run Admin API 建立的函式,需要另外建立及管理事件觸發事件。觸發事件具有預設重試行為,您可以根據函式的需要自訂這些行為。
- 使用 Cloud Functions v2 API 建立的函式會隱含建立必要的事件觸發條件,例如 Pub/Sub 主題或 Eventarc 觸發條件。根據預設,這些觸發事件的重試功能會停用,但您可以使用 Cloud Functions v2 API 重新啟用。
使用 Cloud Run 建立的事件驅動函式
在 Google Cloud 控制台或使用 Cloud Run 管理員 API 建立的函式,需要分別建立及管理事件觸發事件。強烈建議您查看每種觸發事件類型的預設行為:
- Eventarc 重試政策的預設訊息保留時間為 24 小時,並採用指數輪詢方式的延遲機制。請參閱 Eventarc 說明文件,瞭解如何重試事件。
- Pub/Sub 預設會為所有訂閱項目使用「立即重新傳送」政策。請參閱 Pub/Sub 說明文件,瞭解如何處理訊息失敗和重試要求。
使用 Cloud Functions v2 API 建立的事件導向函式
使用 Cloud Functions 第 2 版 API 建立的函式,例如使用 Cloud Functions gcloud CLI、REST API 或 Terraform,會代您建立及管理事件觸發事件。根據預設,如果函式叫用作業因錯誤而終止,系統就不會再次叫用該函式,並且會捨棄事件。在事件驅動函式上啟用重試功能後,Cloud Run 函式會重試失敗的函式叫用,直到成功完成或重試時間窗口到期為止。
如果未為函式啟用重試功能 (這是預設值),函式一律會回報已成功執行,且記錄中可能會顯示 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 函式會使用指數輪詢策略重試新建立的事件導向函式,輪詢間隔會以 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 分鐘。
- 變更指數型回退重試策略的最小和最大回退時間。
- 變更重試策略,以便立即重試。
- 設定無效信件主題。
- 設定傳送嘗試次數上限和下限。
如要設定重試政策,請按照下列步驟操作:
- 編寫 HTTP 函式。
- 使用 Pub/Sub API 建立 Pub/Sub 訂閱項目,並將函式的網址指定為目標。
如要進一步瞭解如何直接設定 Pub/Sub,請參閱 Pub/Sub 的處理失敗情況說明文件。
後續步驟
- 部署 Cloud Run 函式
- 呼叫 Pub/Sub 觸發事件函式
- 呼叫 Cloud Storage 觸發事件函式
- 搭配 Pub/Sub 使用 Cloud Run 函式教學課程
- 搭配 Cloud Storage 使用 Cloud Run 函式教學課程