如何設(shè)計(jì)一個(gè)事件驅(qū)動(dòng)系統(tǒng)?
這篇文章,我們來介紹一種常見且重要的架構(gòu):事件驅(qū)動(dòng)架構(gòu)。
什么是事件驅(qū)動(dòng)架構(gòu)?
事件驅(qū)動(dòng)架構(gòu)(Event-Driven Architecture,簡稱 EDA),它是一種架構(gòu)風(fēng)格,其特征是存在許多相對獨(dú)立的參與者,他們通過事件相互通信以實(shí)現(xiàn)協(xié)調(diào)的目標(biāo)。
事件驅(qū)動(dòng)型架構(gòu)遵循“發(fā)布/訂閱”模式,允許近乎實(shí)時(shí)地分發(fā)有關(guān)業(yè)務(wù)事件的信息,在這種架構(gòu)中,微服務(wù)在實(shí)體或域模型發(fā)生變化時(shí)異步發(fā)布事件,而不是同步調(diào)用 API。事件驅(qū)動(dòng)架構(gòu)通常包含以下組件:
- 事件:事件是系統(tǒng)中發(fā)生的某種特定情況或變化的表示。事件可以是用戶操作(如點(diǎn)擊按鈕)、系統(tǒng)狀態(tài)的變化(如數(shù)據(jù)庫記錄的更新)、外部系統(tǒng)的通知等。
- 事件生產(chǎn)者:事件生產(chǎn)者是生成事件的組件或服務(wù)。當(dāng)某個(gè)特定情況發(fā)生時(shí),事件生產(chǎn)者會(huì)創(chuàng)建一個(gè)事件并將其發(fā)送出去。生產(chǎn)者可以是用戶界面、傳感器、服務(wù)等。
- 事件消費(fèi)者:事件消費(fèi)者是接收和處理事件的組件或服務(wù)。消費(fèi)者訂閱特定類型的事件,并在接收到事件后執(zhí)行相應(yīng)的業(yè)務(wù)邏輯。消費(fèi)者可以是微服務(wù)、函數(shù)、作業(yè)處理器等。
- 事件通道:事件通道是事件在生產(chǎn)者和消費(fèi)者之間傳遞的媒介。常見的事件通道有消息隊(duì)列(如RabbitMQ、Kafka)、事件總線(如AWS EventBridge)、發(fā)布/訂閱系統(tǒng)等。
- 事件處理:事件處理是消費(fèi)者接收到事件后的操作。處理可以是簡單的業(yè)務(wù)邏輯執(zhí)行,也可以是復(fù)雜的工作流,包括調(diào)用其他服務(wù)、更新數(shù)據(jù)庫、觸發(fā)進(jìn)一步的事件等。
到目前為止,全球超過 72%的組織使用 EDA來驅(qū)動(dòng)他們的應(yīng)用程序、系統(tǒng)和流程,比如多人游戲、在線銀行、流媒體服務(wù)以及生成式人工智能。
EDA的工作原理
事件驅(qū)動(dòng)架構(gòu)中的事件代表系統(tǒng)中的發(fā)生或變化,驅(qū)動(dòng)流動(dòng)。它們由各種來源生成,發(fā)布到事件總線或消息代理,并由感興趣的組件異步消費(fèi),以下是事件驅(qū)動(dòng)架構(gòu)的基本原理:
- 事件生成:當(dāng)某個(gè)特定情況發(fā)生時(shí),事件生產(chǎn)者創(chuàng)建一個(gè)事件,并將其發(fā)送到事件通道。
- 事件傳遞:事件通過事件通道傳遞到一個(gè)或多個(gè)事件消費(fèi)者。事件通道負(fù)責(zé)可靠地傳遞事件,確保事件不會(huì)丟失。
- 事件處理:事件消費(fèi)者接收到事件后,執(zhí)行相應(yīng)的業(yè)務(wù)邏輯。處理可以是同步的,也可以是異步的,取決于具體的實(shí)現(xiàn)需求。
- 后續(xù)操作:事件處理完成后,可能會(huì)觸發(fā)新的事件,繼續(xù)驅(qū)動(dòng)系統(tǒng)的操作。這個(gè)過程可以形成一個(gè)復(fù)雜的事件鏈,協(xié)同完成復(fù)雜的業(yè)務(wù)流程。
整個(gè)工作流程可以抽象成下圖:
事件驅(qū)動(dòng)系統(tǒng)利用最終一致性,采用事件溯源和 CQRS(命令和查詢職責(zé)分離:一種將數(shù)據(jù)存儲(chǔ)的讀取和更新操作分離的模式,以提高性能、可擴(kuò)展性和安全性)等技術(shù)。事件溯源將系統(tǒng)狀態(tài)的所有變化捕獲為一系列事件,便于系統(tǒng)在任何時(shí)候進(jìn)行重建。CQRS分離讀取和寫入操作,實(shí)現(xiàn)高效查詢,同時(shí)保持一致性。
通過采用事件驅(qū)動(dòng)架構(gòu),系統(tǒng)能夠異步和獨(dú)立地對事件做出反應(yīng),使其具有可擴(kuò)展性。
如何使用 EDA?
一個(gè)常見的例子是基于 GUI的應(yīng)用程序,例如視頻游戲:應(yīng)用程序根據(jù)用戶的鼠標(biāo)點(diǎn)擊或菜單選擇進(jìn)行工作。這個(gè)類比可以擴(kuò)展到系統(tǒng)層次的功能,用于實(shí)現(xiàn)業(yè)務(wù)邏輯和工作流,遠(yuǎn)遠(yuǎn)超出了最終用戶可能看到的范圍。事件驅(qū)動(dòng)編程通常是給定組件在基于微服務(wù)的架構(gòu)中支持其角色的方式。
Apache Kafka,一種分布式事件流平臺,通常用于事件驅(qū)動(dòng)架構(gòu)中,以實(shí)現(xiàn)高效的事件驅(qū)動(dòng)通信。EDA模式支持實(shí)時(shí)事件處理、事件溯源、命令查詢職責(zé)分離(CQRS)和發(fā)布/訂閱消息傳遞。
當(dāng)這些模式和技術(shù)結(jié)合使用時(shí),可以實(shí)現(xiàn)處理大量事件的可擴(kuò)展和彈性架構(gòu)。各個(gè)組件發(fā)送事件,表示系統(tǒng)級或業(yè)務(wù)級活動(dòng)或請求;這些事件由事件處理平臺收集,用于過濾、增強(qiáng)和分發(fā)給其他相關(guān)或感興趣的組件。組件之間的通信通過每個(gè)組件發(fā)布的微服務(wù)來處理。在組件內(nèi)部,微服務(wù)是使用事件驅(qū)動(dòng)編程模型實(shí)現(xiàn)的。
EDA具有改進(jìn)響應(yīng)能力、靈活性和可擴(kuò)展性等優(yōu)勢,但它也引入了復(fù)雜性,如運(yùn)營開銷、事件排序挑戰(zhàn),以及有效的事件建模和管理的需求。
總之,事件驅(qū)動(dòng)架構(gòu)利用事件驅(qū)動(dòng)編程、事件驅(qū)動(dòng)微服務(wù)和事件處理技術(shù)等架構(gòu)模式,構(gòu)建可擴(kuò)展、靈活、松耦合的系統(tǒng),以處理和處理實(shí)時(shí)事件和工作流。
通過應(yīng)用EDA模式并考慮相關(guān)的優(yōu)點(diǎn)和權(quán)衡,組織可以設(shè)計(jì)和部署能夠擴(kuò)展和適應(yīng)不斷變化的業(yè)務(wù)需求的健壯系統(tǒng)。
使用案例
在實(shí)際工作中 EDA 有著廣泛的使用,這里列舉了一些常見的 EDA 使用領(lǐng)域:
- 電子商務(wù)訂單處理:當(dāng)客戶下訂單時(shí),會(huì)觸發(fā)一個(gè)事件以啟動(dòng)庫存管理、支付處理和運(yùn)輸協(xié)調(diào)。
- 物聯(lián)網(wǎng)(IoT)數(shù)據(jù)收集:當(dāng)傳感器數(shù)據(jù)超過某個(gè)閾值時(shí),IoT設(shè)備會(huì)生成事件,使得實(shí)時(shí)監(jiān)控和分析各種應(yīng)用成為可能。
- 用戶注冊和認(rèn)證:當(dāng)用戶注冊或登錄時(shí),會(huì)觸發(fā)事件以驗(yàn)證憑據(jù)、更新用戶資料并授予對不同系統(tǒng)資源的訪問權(quán)限。
- 通知系統(tǒng):當(dāng)滿足特定條件時(shí),例如收到新消息或分配任務(wù),會(huì)觸發(fā)事件通知相關(guān)用戶通過電子郵件、短信或推送通知。
- 股票市場交易:當(dāng)市場條件變化時(shí),會(huì)生成事件以觸發(fā)自動(dòng)交易策略,實(shí)現(xiàn)買賣訂單的實(shí)時(shí)執(zhí)行。
- 實(shí)時(shí)分析:當(dāng)數(shù)據(jù)流接收時(shí),會(huì)觸發(fā)事件,允許持續(xù)分析和洞察生成,例如監(jiān)控網(wǎng)站流量或檢測欺詐活動(dòng)。
- 工作流管理:當(dāng)任務(wù)完成或達(dá)到里程碑時(shí),會(huì)觸發(fā)事件以推進(jìn)工作流,確保無縫協(xié)作和流程自動(dòng)化。
- 智能家居中的傳感器集成:當(dāng)傳感器檢測到運(yùn)動(dòng)、溫度變化或門的開啟時(shí),會(huì)生成事件,觸發(fā)動(dòng)作如開燈或調(diào)整恒溫器設(shè)置。
- 事件驅(qū)動(dòng)微服務(wù):事件用于不同微服務(wù)之間的通信,實(shí)現(xiàn)松耦合和可擴(kuò)展的系統(tǒng)。
- 在線游戲:當(dāng)玩家執(zhí)行動(dòng)作時(shí),會(huì)觸發(fā)事件,例如移動(dòng)角色或完成任務(wù),允許參與者之間的實(shí)時(shí)交互和游戲同步。
下面以 Kafka、Flink和Confluent 用于大規(guī)模完全托管的事件驅(qū)動(dòng)架構(gòu)為例進(jìn)行說明:
EDA模式基于松耦合系統(tǒng)通過事件異步通信的原則,事件代表系統(tǒng)或工作流中的重要發(fā)生或變化,實(shí)現(xiàn)這一模式的理想框架是 Apache Kafka。
Kafka是一種開源的流數(shù)據(jù)管道框架,用于實(shí)時(shí)收集、存儲(chǔ)和處理事件及其數(shù)據(jù)。Kafka充當(dāng)高度可擴(kuò)展和容錯(cuò)的事件代理,提供可靠的事件存儲(chǔ)和傳遞。它通過提供事件流的強(qiáng)大基礎(chǔ)來幫助管理事件驅(qū)動(dòng)系統(tǒng)的復(fù)雜性。Kafka擁有豐富的工具、連接器和管理功能生態(tài)系統(tǒng),使組織能夠高效地構(gòu)建、管理和擴(kuò)展事件驅(qū)動(dòng)系統(tǒng)。
Confluent提供 Apache Kafka作為本地軟件,也作為完全托管的云服務(wù)。作為托管服務(wù),Confluent擴(kuò)展了 Kafka的強(qiáng)大功能,如用于管理和監(jiān)控Kafka集群的集中控制平面,以及用于將Kafka與其他應(yīng)用程序連接的連接器和集成。這些功能使企業(yè)能夠更輕松地訪問、存儲(chǔ)和管理數(shù)據(jù),作為連續(xù)的實(shí)時(shí)流。
Confluent被認(rèn)為是事件驅(qū)動(dòng)架構(gòu)的最佳解決方案,因?yàn)槠鋰@ Apache Kafka構(gòu)建的全面和可擴(kuò)展平臺,提供高性能、容錯(cuò)的事件流能力,以及豐富的工具、連接器和管理功能生態(tài)系統(tǒng),使組織能夠高效地構(gòu)建、管理和擴(kuò)展事件驅(qū)動(dòng)系統(tǒng)。
Confluent的托管服務(wù)還將提供 Apache Flink的 SQL功能。Flink是一個(gè)開源的流處理框架,通過高級事件時(shí)間處理、有狀態(tài)計(jì)算、容錯(cuò)和批處理功能,為EDA模式帶來了更多的能力和功能。
Kafka 和 Flink共同實(shí)現(xiàn)了從多個(gè)來源捕獲事件和數(shù)據(jù)的廣泛功能,這些數(shù)據(jù)可以通過強(qiáng)大且可擴(kuò)展的數(shù)據(jù)管道和流處理進(jìn)行處理、過濾和進(jìn)一步增強(qiáng),以供其他下游消費(fèi)者和微服務(wù)使用。
除了Kafka 和 Flink,Confluent作為事件流平臺的領(lǐng)導(dǎo)者,還提供額外的功能以應(yīng)對實(shí)施 EDA模式的復(fù)雜性和挑戰(zhàn):
- Kafka Streams:一個(gè)輕量級的Java庫,與Apache Kafka緊密集成。開發(fā)人員可以使用它通過直接處理 Kafka主題中的數(shù)據(jù)并將結(jié)果生成回 Kafka,構(gòu)建實(shí)時(shí)應(yīng)用程序和微服務(wù)。由于它是 Kafka的一部分,Kafka Streams本身就利用了 Kafka的優(yōu)勢。
- Schema Registry:Confluent Schema Registry允許在事件驅(qū)動(dòng)系統(tǒng)中進(jìn)行集中式模式管理。它使模式在時(shí)間上演變,同時(shí)確保向后兼容。這通過提供管理事件格式演變的機(jī)制,幫助解決事件一致性挑戰(zhàn)。
- 監(jiān)控和可觀察性:Confluent提供監(jiān)控和可觀察性工具和功能,使開發(fā)人員和操作人員能夠深入了解其事件驅(qū)動(dòng)系統(tǒng)的健康狀況和性能。這些工具通過提供事件流動(dòng)可見性、性能指標(biāo)和錯(cuò)誤跟蹤,幫助調(diào)試和故障排除。
- 安全性和加密:Confluent提供一系列功能來保護(hù)和審計(jì)敏感數(shù)據(jù),并防止未經(jīng)授權(quán)的訪問,這有助于在實(shí)施事件驅(qū)動(dòng)架構(gòu)時(shí)解決重要的安全考慮,尤其是在數(shù)據(jù)隱私和安全至關(guān)重要的企業(yè)環(huán)境中。
- 數(shù)據(jù)連接性:Confluent提供廣泛的數(shù)據(jù)連接器,可在Kafka與其他數(shù)據(jù)源或接收器之間無縫地?cái)z取或?qū)С鰯?shù)據(jù)。這些包括Kafka Connect(一個(gè)用于構(gòu)建和運(yùn)行Kafka連接器的開源框架)、Confluent連接器(Confluent支持的JDBC、Elasticsearch、Amazon S3連接器、HDFS、Salesforce、MQTT和其他流行數(shù)據(jù)源的連接器)、社區(qū)連接器(由社區(qū)成員貢獻(xiàn)和維護(hù))和自定義連接器(由組織自己的開發(fā)人員構(gòu)建)。
- 生態(tài)系統(tǒng)集成:Confluent提供與事件驅(qū)動(dòng)架構(gòu)中常用的各種工具和框架的集成,如Apache Flink、Apache Spark和Kubernetes。這些集成簡化了在現(xiàn)有基礎(chǔ)設(shè)施和工具中采用和管理事件驅(qū)動(dòng)系統(tǒng)。
EDA的優(yōu)點(diǎn)
事件驅(qū)動(dòng)架構(gòu)包含很多優(yōu)點(diǎn),以下列舉了事件驅(qū)動(dòng)架構(gòu)的最顯著的幾個(gè)優(yōu)點(diǎn):
(1) 松耦合和可擴(kuò)展性
EDA通過使用事件解耦組件,促進(jìn)了組件之間的松耦合。在EDA中,組件通過異步事件消息進(jìn)行交互,使它們能夠獨(dú)立開發(fā)、部署和擴(kuò)展。這種松耦合使系統(tǒng)具有更好的模塊化、靈活性和敏捷性??梢蕴砑踊蛐薷男陆M件而不影響現(xiàn)有組件,便于擴(kuò)展和適應(yīng)不斷變化的業(yè)務(wù)需求。
(2) 實(shí)時(shí)處理和響應(yīng)能力
EDA通過響應(yīng)事件的發(fā)生實(shí)現(xiàn)實(shí)時(shí)處理和響應(yīng)能力。事件,如用戶交互、系統(tǒng)通知或外部觸發(fā),被捕獲并近實(shí)時(shí)處理。這確保了系統(tǒng)能夠快速響應(yīng)變化,實(shí)現(xiàn)更快的決策、實(shí)時(shí)分析和即時(shí)行動(dòng)。EDA特別適用于實(shí)時(shí)數(shù)據(jù)處理和響應(yīng)能力至關(guān)重要的用例,如金融系統(tǒng)、IoT應(yīng)用或?qū)崟r(shí)監(jiān)控。
(3) 可靠性和容錯(cuò)性
EDA通過利用事件驅(qū)動(dòng)通信增強(qiáng)系統(tǒng)的可靠性和容錯(cuò)性。事件可以記錄并存儲(chǔ)在持久事件存儲(chǔ)中,提供過去事件的審計(jì)跟蹤。這允許錯(cuò)誤處理、恢復(fù)和事件重放,確保容錯(cuò)和系統(tǒng)彈性。在發(fā)生故障時(shí),可以通過重放事件將組件恢復(fù)到一致狀態(tài),提供可靠和一致的系統(tǒng)。
(4) 與不同系統(tǒng)的無縫集成
EDA促進(jìn)了與不同系統(tǒng)和技術(shù)的無縫集成。由于組件通過事件進(jìn)行通信,它們可以在不同系統(tǒng)之間交換數(shù)據(jù)和觸發(fā)操作。這使得數(shù)據(jù)交換和互操作性更加高效,因?yàn)槭录梢杂筛鞣N系統(tǒng)消費(fèi)和生成,而不論其底層技術(shù)或編程語言。EDA支持創(chuàng)建集成微服務(wù)、遺留系統(tǒng)、云服務(wù)和第三方應(yīng)用程序的事件驅(qū)動(dòng)架構(gòu)。
總體而言,事件驅(qū)動(dòng)架構(gòu)提供了技術(shù)優(yōu)勢,使組織能夠構(gòu)建靈活、可擴(kuò)展、響應(yīng)迅速和可靠的系統(tǒng)。通過采用松耦合、實(shí)時(shí)處理、容錯(cuò)和無縫集成,EDA使得開發(fā)能夠滿足現(xiàn)代應(yīng)用程序需求的健壯和敏捷系統(tǒng)成為可能。
EDA的缺點(diǎn)
雖然 EDA提供了眾多好處,但它也存在一些挑戰(zhàn):
(1) 復(fù)雜性
與傳統(tǒng)的單體架構(gòu)相比,EDA引入了額外的復(fù)雜性。它需要事件生產(chǎn)者、事件消費(fèi)者、事件代理和其他組件,這會(huì)增加整體系統(tǒng)的復(fù)雜性。
(2) 事件排序
在事件驅(qū)動(dòng)系統(tǒng)中確保事件的正確順序可能具有挑戰(zhàn)性。某些用例,如金融交易或數(shù)據(jù)一致性,可能需要嚴(yán)格的事件排序,這需要仔細(xì)的設(shè)計(jì)和實(shí)現(xiàn)。
(3) 最終一致性
在分布式系統(tǒng)中,實(shí)現(xiàn)跨多個(gè)服務(wù)或組件的事件一致性可能很困難。維護(hù)數(shù)據(jù)完整性并確保所有相關(guān)系統(tǒng)正確響應(yīng)事件可能是一項(xiàng)復(fù)雜的任務(wù)?;贓DA的架構(gòu)面臨相同的挑戰(zhàn)。
(4) 調(diào)試和故障排除
在事件驅(qū)動(dòng)系統(tǒng)中識別和診斷問題可能比傳統(tǒng)的請求-響應(yīng)系統(tǒng)更復(fù)雜。事件可以觸發(fā)跨各種組件的一系列反應(yīng),使得跟蹤流動(dòng)和識別問題的根本原因變得具有挑戰(zhàn)性。
總結(jié)
本文我們詳細(xì)的分析了事件驅(qū)動(dòng)架構(gòu),EDA 是一種很常見的軟件設(shè)計(jì)模式,通過松耦合組件和異步通信,促進(jìn)靈活性、可擴(kuò)展性和容錯(cuò)性等特性,使系統(tǒng)能夠?qū)崟r(shí)檢測、處理和響應(yīng)事件。
盡管 EDA有很多優(yōu)點(diǎn),但它同時(shí)給系統(tǒng)帶來復(fù)雜性和調(diào)試挑戰(zhàn),因此,在 EDA 選擇時(shí),需要根據(jù)真實(shí)的業(yè)務(wù)權(quán)衡。