什麼是事件驅動架構 (EDA)?
事件驅動架構 (EDA) 是一種現代架構模式,由發佈、使用或路由事件的小型解耦服務建置而成。
事件代表狀態的變更或更新。例如:放入購物車的商品、上傳至儲存系統的檔案或準備出貨的訂單。事件可以帶有狀態 (例如訂單中的商品名稱、價格或數量),也可以僅包含查詢相關資訊所需的識別符 (例如,「訂單 #8942 已出貨」)。
與傳統的請求驅動模型不同,EDA 可促進生產者和使用者服務之間的鬆耦合。這樣一來,即可更加輕鬆地擴展、更新和獨立部署系統的單獨元件。
為什麼解耦架構很重要?
許多組織發現,整合型應用程式、資料庫和技術會對創新和改善使用者體驗造成負面影響。舊式應用程式和資料庫減少了您採用現代技術架構的選擇,並限制了您的競爭力和創新。但是,當您對應用程式及其資料存放區進行現代化改造時,它們會變得更容易擴展和更快地開發。
解耦資料策略提高了容錯能力和彈性,有助於加快新應用程式功能的上市時間 (TTM)。
如需有關現代化整合型應用程式的優勢的詳細資訊,請參閱《AWS 方案指引》中的在微型服務中啟用資料持續性。
事件驅動架構 (EDA) 有哪些優勢?
事件驅動架構 (EDA) 可促進系統元件之間的鬆耦合,進而提高敏捷性。微型服務可以獨立擴展,在不影響其他服務的情況下失敗,並降低工作流程的複雜性。可以靈活地路由、緩沖和記錄事件,以用於稽核目的。基於推送的事件流可即時運行,從而降低了與建立和運行程式碼相關的成本,其中該程式碼會不斷地輪詢系統以進行變更。
獨立擴展和失敗
透過解耦服務,事件驅動架構中的元件可以獨立擴展和失敗,從而提高應用程式的彈性。隨著服務之間整合數量不斷增加,這一點變得越來越重要。若一項服務有故障,其餘仍能繼續運作。
事件驅動架構還可使設計近乎即時的系統變得更加容易,幫助組織免去批次處理。應用程式狀態變更時,將會產生事件。隨著事件的擴展,處理事件的層也將擴大。
事件通常會發佈到簡訊服務,其行為類似於微型服務之間的彈性緩衝區並幫助處理擴展。事件也可能被傳送到路由器服務,該服務可根據事件的內容篩選和路由訊息。因此,事件型應用程式可以比整合型應用程式更具可擴展性並提供更大的冗餘。
敏捷開發
藉助事件驅動架構和事件路由器,開發人員不再需要編寫自訂程式碼來輪詢、篩選和路由事件。事件路由器會自動篩選事件,並將事件推送給取用者。路由器還能免除生產者與取用者服務之間大量協調的需要,提高開發人員敏捷性。
事件驅動架構是以推送為基礎,這意味著當事件傳送至路由器和下游系統時,一切皆隨需執行,而無需通知相依服務。因此,基礎設施和資源可以隨著事件數量的變化而擴充和縮減,從而降低處理工作負載和運行已部署應用程式的成本。
建置可擴展系統
事件驅動架構也具有高度可擴展性。其他團隊可以在不影響現有微型服務的情況下擴展特性和新增功能。透過發佈事件,應用程式可以與現有系統整合——未來的應用程式可以作為事件取用者輕鬆整合——而無需變更現有解決方案。
事件生產者不了解事件取用者,因此擴展系統的摩擦較小,並且新功能或整合不會新增會減緩未來開發的相依性。
降低複雜性
微型服務使開發人員和架構師能夠分解複雜的工作流程。例如,他們可以將電子商務巨型應用程式分解為具有獨立庫存、配送和會計服務的訂單接受和支付程序。
在巨型應用程式中管理和協調可能很複雜的工作負載變成了一系列簡單的解耦服務,而這些服務可單獨進行管理並透過事件訊息非同步通訊。
事件驅動方法可以組裝和協調以不同速率處理資料的服務。在以下範例中,訂單接受微型服務透過佇列與支付處理系統互動。
在範例中,訂單接受服務可以透過在佇列中緩衝訊息來儲存大量傳入訂單。
由於處理付款的複雜性,支付處理服務通常較慢,且其可以從佇列中獲取穩定的訊息串流。由於重試和錯誤處理邏輯,支付服務可在各種系統狀態之間轉換。工作流程服務根據系統狀態協調和管理支付步驟,並最終產生更多與庫存、配送和會計服務相關的事件。
輕鬆稽核
事件驅動架構中的事件路由器可作為集中位置,供您稽核應用程式,訂定原則。這些原則能限制誰能發佈和訂閱路由器,以及控制哪些使用者和資源具有權限,可存取您的資料。您也能為傳輸中和靜態的事件加密。
降低成本
EDA 是以推送為基礎,因此事件出現在路由器中時,一切皆隨需執行。如此一來,您就不必為了持續輪詢以檢查有無事件,而付出相關成本。因此,可使網路頻寬耗用量降低、CPU 利用率減少,閒置機群容量縮小,SSL/TLS 訊號交換也更少。
事件驅動架構 (EDA) 如何運作?
以下舉電子商務網站的事件驅動架構 (EDA) 為例:
此範例站點顯示了三個主要的事件生產者元件以及它們產生的事件。在這種情況下,事件路由器會擷取和篩選事件,然後將一個或多個事件傳送給事件取用者。
事件驅動架構讓該網站能在尖峰需求時刻因應出自各種來源的變化,不致損毀應用程式,亦未過度佈建資源。
哪些類型的工作負載適合事件驅動架構 (EDA)?
事件驅動架構 (EDA) 可以提供一種有效的方式來滿足高度可擴展和高度可用的工作負載的需求。EDA 還適用於具有不可預測或「尖峰」流量模式的工作負載。
事件驅動架構 (EDA) 如何改進應用程式?
事件驅動架構 (EDA) 可促進元件之間的鬆耦合,進而能夠更好地建置現代分散式應用程式。
事件生產者不知道、不關心他們生產的事件的下游取用者的任何活動,並且不會為此負擔。事件本身代表狀態的變化,可能包含也可能不包含資料。事件並不了解它們存在的後果。取用者收聽並處理相關事件。您可以在不中斷現有工作流程的情況下,讓新取用者上線以提供新功能。
EDA 可促進將整合型系統分解為更小的網域模型。開發人員可用更少的認知負擔快速上手,並更快地提高生產力。當解耦關鍵函數時,部署更新和新功能的風險也更低。
常見的事件驅動架構 (EDA) 使用案例有哪些?
針對 Web 和行動後端的微型服務通訊
零售或媒體和娛樂網站通常必須擴大規模,以處理不可預測的流量。客戶存取電子商務網站並下訂單。訂單事件可傳送到事件路由器。所有下游微型服務都可以獲取訂單事件進行處理。範例動作可能包括:提交訂單、授權付款以及將訂單詳細資訊傳送給貨運供應商。
由於每個微型服務都可以獨立擴展和失敗,因此該流程可以在訂單高峰期擴展而不會出現單一故障點。
業務工作流程自動化
許多業務工作流程 (例如金融服務交易) 需要重複相同的步驟。您可以使用事件驅動架構 (EDA) 啟動和自動化這些步驟。
例如,當客戶向銀行申請新帳戶時,銀行必須進行一些資料檢查 (身分證明文件、地址等)。一些帳戶還需要人工核准階段。您可以透過工作流程服務協調所有這些步驟,而該服務會在收到新帳戶申請時自動執行步驟。
您還可以新增一個工作流程,透過機器學習非同步處理客戶應用程式資料以擷取相關資料,從而可能節省數小時的手動資料收集和驗證時間。
SaaS 應用程式整合
軟體即服務 (SaaS) 環境面臨的最大挑戰是缺乏對使用者活動和資料的可見性。為了解鎖孤立資料,事件驅動架構可以擷取 SaaS 應用程式事件或將事件傳送到他們的 SaaS 應用程式。例如,您可建置中介軟體來擷取傳入的合作夥伴訂單資料,並將訂單直接傳送到內部訂單處理應用程式。
基礎設施和自動化
在執行運算密集型工作負載 (例如財務分析、基因體研究或媒體轉碼) 時,您可以透過擴展運算資源以進行高度並行處理,然後在作業完成後縮減運算資源。
例如,在高度管制產業中,擁有 EDA 的公司可以啟動安全狀態資源以回應事件,或者在安全策略傳送提醒事件時採取補救措施。
您該何時採用事件驅動架構 (EDA)?
事件驅動架構 (EDA) 是提升敏捷性,迅速移動的理想選擇。在使用微型服務的現代應用程式,或有解耦元件的任何應用程式中經常存在。
異質系統的整合
如您有在不同堆疊上執行的系統,可使用 EDA 在之間共用資訊,無需耦合。事件路由器能在系統之間形成間接性與相互操作性,因此能夠交換訊息和資料,同時維持不相關。
跨區域、跨帳戶的資料複製
您可使用 EDA,為團隊操作的系統、以及部署在各 AWS 區域和帳戶之間的系統進行協調。藉由以事件路由器在系統之間傳輸資料,您可獨立於其他團隊,開發、擴展和部署服務。
資源狀態的監控和提醒
與其持續檢查資源,您可使用 EDA 監控任何異常、變更和更新,並接收提醒。這些資源可以包含儲存貯體、資料庫表格、無伺服器函數、運算節點及其他項目。
散發和平行處理
如您有許多系統必須因應事件而操作,則您可使用 EDA 散發事件,無需為了推送至各取用者而編寫自訂程式碼。路由器會將事件推送至系統,各自為不同的用途平行處理事件。
常見的事件驅動架構 (EDA) 模式有哪些?
多個短函數
建立許多短函數,而減少較大的函數。為您的工作負載建立高度專業的函數,這意味著它們簡單明瞭並且通常可以減少處理時間。每個函數都應該處理傳遞給函數的事件,而不需要了解或期望整個工作流程或交易量。這樣一來,函數將與事件來源無關,且與其他服務的耦合最小。
隨需處理而非批次處理
許多傳統系統設計為定期執行並處理隨時間累積的批量交易。例如,銀行應用程式可能每小時執行一次,以在中央總帳中處理 ATM 交易。
在事件驅動架構 (EDA) 中,自訂處理可以回應每個事件。這允許服務根據需要擴展並行,以近乎即時地處理交易。
中斷復原
在中斷的情況下,可能會自動叫用服務以重試處理事件。因為服務可能會多次接收相同的事件,所以將函數設計為具有等冪性。這樣一來,即可確保在服務第一次接收事件後,結果不會改變。
例如,如果零售商由於重試而嘗試處理信用卡兩次,則服務僅在第一次嘗試時處理付款。在重試時,服務會驗證支付狀態並捨棄該事件。
事件驅動架構 (EDA) 有哪些挑戰?
採用事件驅動架構 (EDA) 時,您可能需要重新思考對於應用程式設計的觀點。
變數延遲
整合型應用程式可能會在單一裝置上處理相同記憶體空間內的所有內容,而事件驅動應用程式則與之不同,其可跨網路進行通訊。這種設計引入了變數延遲。儘管整合型應用程式可能具有更低或更少的變數延遲,但這通常是以犧牲可擴展性和可用性為代價而實現的。
無伺服器 AWS 服務具有高可用性,也就是說它們在一個 AWS 區域的多個可用區域中運行。如果發生服務中斷,服務會自動容錯移轉到備用可用區域並重試交易。因此,交易並不會失敗,而可能會成功完成,但具有較高延遲。
需要一致的低延遲效能的工作負載不適合 EDA。兩個範例是銀行中的高頻交易應用程式或倉儲中低於一毫秒的機器人自動化。
最終一致性
事件代表狀態的變更。由於許多事件在任何給定時間點通過架構中的不同服務,因此此類工作負載通常為最終一致性。 這使得處理交易、處理重複項目或確定系統的確切整體狀態變得更加複雜。
由於需要 ACID 屬性,某些工作負載不太適合 EDA。但是,許多工作負載包含最終一致性 (例如,當前小時內的總訂單) 或高度一致性 (例如,當前庫存) 的需求組合。對於需要高度資料一致性的那些功能,有一些架構模式可以為此提供支援。例如:
- 您可以將關聯式資料庫用於需要 ACID 屬性的功能,儘管任何關聯式資料庫的可擴展性都低於 NoSQL 資料存放區。
向呼叫者傳回值
在許多情況下,事件型應用程式為非同步。這意味著,呼叫者服務在繼續其他工作之前不會等待來自其他服務的請求。EDA 的這一基本特性支援可擴展性和靈活性;但是,它使傳遞傳回值或工作流結果比在同步流程中更複雜。
在許多情況下,傳回一個值不如確保處理事件的成功或失敗重要。確保事件處理的功能可能比將值傳回給呼叫者更重要。
對於互動式工作負載,例如 Web 和行動應用程式,最終使用者通常希望收到傳回值或交易的當前狀態。對於這些工作負載,有幾種設計模式可以將豐富的事件傳回給呼叫者。但是,事件驅動架構中的這些實作比使用傳統的異步傳回值更複雜。該平台通常可以減輕這種複雜性。
跨服務和函數偵錯
偵錯事件驅動系統與偵錯整合型應用程式不同。與所有以微型服務為基礎的應用程式以及傳遞事件的不同系統和服務一樣,在發生錯誤時記錄和重現多個服務的確切狀態會是一項挑戰。由於每個服務和函數叫用都有單獨的日誌檔案,因此確定導致錯誤的特定事件發生了什麼可能會更加複雜。
協同運作
隨著時間的推移,簡單的工作流程變得更加複雜也就不足為奇了。在典型的巨型應用程式中,這可能會導致更緊密耦合的函數和服務群組,以及複雜的程式碼處理路由和例外。
為了追蹤系統的狀態,涉及分支邏輯、不同類型的故障模型和重試邏輯的工作流程通常會使用協調器。在建立事件驅動無伺服器應用程式時,務必要確定何時會發生這種情況,以便您可以將此邏輯遷移到狀態機器,以進行適當的協同運作。
哪些 AWS 服務會使用事件驅動架構 (EDA)?
AWS 服務通常會產生或使用事件,從而可以輕鬆建置具有事件驅動架構 (EDA) 的解決方案。
此外,Amazon EventBridge、Amazon SNS、Amazon SQS 和 AWS Step Functions 等服務包括可幫助客戶編寫較少的未定案程式碼及更快建置 EDA 的功能。
Amazon EventBridge
您可以使用 Amazon EventBridge,以利用來自 SaaS 應用程式、其他 AWS 服務或自訂應用程式的事件為事件驅動應用程式大規模建置事件匯流排。
EventBridge 套用規則,即將事件從事件來源路由到不同的目標。目標可以包括 AWS 服務,例如 AWS Lambda、Step Functions 和 Amazon Kinesis,或通過 EventBridge API 目的地的任何 HTTP 端點。
EDA 使用的一個熱門整合是 Step Functions,其中事件會觸發特定工作流程。
AWS Step Functions
AWS Step Functions 包括 Workflow Studio,這是一種低程式碼視覺化工作流程設計器,而建置者可以使用它來協調不同的 AWS 服務。您可以使用 Workflow Studio 來建置分散式應用程式、自動化 IT 和業務程序,以及使用 AWS 服務建置資料和機器學習管道。
Amazon SNS
我們建議使用 Amazon Simple Notification Service (Amazon SNS) 建置對其他應用程式、微型服務或 AWS 服務發佈的高吞吐量和低延遲事件做出反應的應用程式。您還可以將 Amazon SNS 用於需要極高散發量 (數千個或數百萬個端點) 的應用程式。
Amazon SQS
Amazon Simple Queue Service (Amazon SQS) 提供安全、耐久且可用的託管佇列服務,您可以使用它來整合及解耦分散式軟體系統和元件。Amazon SQS 提供常見的結構,例如無效字母佇列和成本分配標籤。