瞭解如何使用 Azure Functions 搭配 Azure 事件中樞觸發程式建置健全且可靠的無伺服器解決方案。 本文涵蓋檢查點、錯誤處理和實作斷路器模式的最佳做法,以確保不會遺失任何事件,且事件驅動應用程式保持穩定且具復原性。
分散式系統中事件數據流的挑戰
請考慮以每秒 100 個事件的固定速率傳送事件的系統。 如此一來,在幾分鐘內,多個平行實例就可以每秒取用傳入的 100 個事件。
不過,請考慮在取用事件流時面臨的這些挑戰:
- 事件發行者會傳送損壞事件。
- 您的函式程式代碼遇到未處理的例外狀況。
- 下游系統離線並封鎖事件處理。
不同於處理期間鎖定訊息的 Azure 佇列儲存體觸發程序,Azure 事件中樞會在每個分割區的串流中從單一點讀取。 此讀取行為類似於視頻播放器,提供了高吞吐量、多個消費者群組和重播能力所需的優勢。 從檢查點向前或向後讀取事件,但您必須移動指標才能處理新事件。 如需詳細資訊,請參閱事件中樞檔中的 檢查點 。
當數據流中發生錯誤,而您選擇不前進指標時,會封鎖進一步的事件處理。 換句話說,如果停止指標來處理處理單一事件的問題,未處理的事件就會開始堆積。
不論成功或失敗為何,函數都會移動資料流的指標,以避免死結。 因為指標會持續前進,因此您的函式必須適當地處理失敗。
事件中樞觸發程序如何取用事件
Azure Functions 會依照以下步驟循環,從事件中心接收事件:
- 系統會針對事件中樞的每個分割區建立指標,並保存在 Azure 記憶體中。
- 新事件會以批次的方式接收 (預設),而且主機會嘗試觸發提供事件批次進行處理的函式。
- 當函式完成執行(不論是否有例外發生)時,指標會向前移動,並將檢查點儲存至預設主機的儲存帳戶。
- 如果條件會防止函式執行完成,主機就無法前進指標。 當指標無法前進時,後續執行會重新處理相同的事件。
此行為會顯示一些重要點:
未處理的例外狀況可能會導致您遺失事件:
引發例外狀況的函式執行會使指標繼續前進。 設定 重試原則 或其他重試邏輯會延遲指標前進,直到整個重試完成為止。
Azure Functions 會保證至少一次傳遞:
您的程式代碼和相依系統可能需要考慮相同事件可以處理兩次的事實。 如需詳細資訊,請參閱 設計 Azure Functions 以處理相同的輸入。
處理例外狀況
雖然所有函式程式代碼都應該在最高層級的程式代碼中包含 try/catch 區塊 ,但對於取用事件中樞事件的函式而言,擁有 catch 區塊更為重要。 如此一來,當例外狀況被引發時,捕捉區塊會在指標移動之前處理錯誤。
重試機制和原則
因為雲端中的許多例外狀況都是暫時性的,因此錯誤處理的第一個步驟一律會重試作業。 您可以套用內建的重試原則,或定義您自己的重試邏輯。
重試原則
Azure Functions 會提供事件中樞的內建重試原則。 使用重試原則時,您只需引發新的例外狀況,主機就會嘗試根據定義的原則再次處理事件。 此重試行為需要事件中樞擴充功能 5.x 版或更新版本。 如需詳細資訊,請參閱重試原則。
自定義重試邏輯
您也可以在函式本身中定義自己的重試邏輯。 例如,您可以實作遵循下列規則所說明工作流程的原則:
- 嘗試處理事件三次(可能在重試之間會有延遲)。
- 如果所有重試的最終結果是失敗,請將事件新增至佇列,讓處理可以在數據流上繼續。
- 稍後會再行處理那些已損毀或未經處理的事件。
備註
Polly 是 C# 應用程式的復原和暫時性錯誤處理連結庫範例。
非異常錯誤
有時候問題可能會發生,卻不會引發例外狀況。 例如,假設要求逾時或執行函式的實例當機。 當函式因未拋出例外而無法完成時,位移指標將不會進階。 如果指標未前進,則在執行失敗後執行的任何實例都會繼續讀取相同的事件。 這種情況會提供至少一次保證。
保證處理每個事件至少一次表示某些事件可以多次處理。 您的函式應用程式必須注意這種可能性,而且必須以 等冪性原則為基礎來建置。
處理失敗狀態
您的應用程式可能能夠成功地處理事件處理中的少許錯誤。 不過,您也應該準備好處理持續性失敗狀態,這可能會因為下游處理失敗而發生。 在這類失敗狀態中,例如下游數據存放區離線,您的函式應該停止對事件進行觸發,直到系統恢復正常運行為止。
斷路器模式
當您實作 斷路器 模式時,您的應用程式可以有效地暫停事件處理,然後在問題解決之後稍後繼續。
在事件串流進程中實作斷路器需要兩個元件:
- 在所有實例上共享狀態,以追蹤和監視線路的健康情況。
- 可以管理線路狀態的主要進程,可以是
open或closed。
實作的詳細內容可能會有所不同,但要在實體之間共享狀態,則必須具備一個儲存機制。 您可以將狀態儲存在 Azure 記憶體、Redis 快取或任何其他可由函式應用程式實例存取的持續性服務中。
Durable Functions 和 Azure Logic Apps 都提供基礎結構來管理工作流程和線路狀態。 本文說明如何使用 Logic Apps 暫停和重新啟動函式執行,提供您所需的控制權來實作斷路器設計模式。
定義跨實例的失敗臨界值
當多個實例同時處理事件時,需要持續共享的外部狀態來監測系統狀況。 然後,您可以根據指出失敗狀態的規則來監視此持續性狀態,例如:
在所有實例的 30 秒內發生超過 100 個事件失敗時,請斷路以停止觸發新事件。
此監視邏輯的實作詳細數據會根據您的特定應用程式需求而有所不同,但一般而言,您必須建立一個系統:
- 將失敗記錄到持久化儲存。
- 檢查記錄新失敗時的滾動計數,以判斷是否符合事件失敗閾值。
- 符合此臨界值時,發出事件,告知系統中斷線路。
使用 Azure Logic Apps 管理線路狀態
Azure Logic Apps 隨附不同服務的內建連接器以及具狀態協調流程,而且是管理線路狀態的自然選擇。 偵測線路何時必須中斷之後,您可以建置邏輯應用程式來實作此工作流程:
- 觸發事件方格工作流程,以停止函式處理。
- 傳送通知電子郵件,其中包含重新啟動工作流程的選項。
若要瞭解如何使用應用程式設定停用和重新啟用特定函式,請參閱 如何在 Azure Functions 中停用函式。
電子郵件收件者可以調查線路的健康情況,並視需要透過通知電子郵件中的連結重新啟動線路。 當工作流程重新啟動函式時,會從最後一個事件中樞檢查點處理事件。
當您使用此方法時,不會遺失任何事件、依序處理事件,而且您可以視需要中斷線路。
事件方格觸發程式的移轉策略
當您在區域之間或某些方案之間移轉現有的函數應用程式時,必須在移轉過程中重新建立應用程式。 在此情況下,在移轉過程中,您可能會有兩個應用程式能夠從相同的事件數據流取用,並寫入相同的輸出目的地。
您應該考慮 使用取用者群組 ,以避免在移轉過程中發生事件資料遺失或重複:
為新的目標應用程式建立新的取用者群組。
在新的應用程式中設定觸發器,以使用這個新的使用者群組。
這可讓這兩個應用程式在驗證期間獨立處理事件。
驗證新應用程式正在正確處理事件。
停止原始應用程式,或移除其訂用帳戶/取用者群組。