什麼是事件驅動架構(EDA)? 一個會寫詩的程序員

EDA, Event-Driven Architecture

What is an event?

Event, something that happens at a given place and time.

Simply put, the event is a significant change in state, which is triggered when a user takes an action.

事件,本質上就是運動,變化,跟“函數”、“消息”、“操作”、“調用”、“算子”、“映射”等概念全息。

For example:

When a customer buys a car and its state changes from For Sale to Sold is an event.
After a successful transaction, when an amount gets deducted from your account is an event.
Once clicking on the book cab button, when a cab is booked from your account is an event.

Every event may trigger one or more than one options in response.

事件,在計算機領域裏指:可以被控件識別的操作,如按下確定按鈕,選擇某個單選按鈕或者複選框。每一種控件有自己可以識別的事件,如窗體的加載、單擊、雙擊等事件,編輯框(文本框)的文本改變事件,等等。

事件有系統事件和用戶事件。系統事件由系統激發,如時間每隔24小時,銀行儲戶的存款日期增加一天。用戶事件由用戶激發,如用戶點擊按鈕,在文本框中顯示特定的文本。事件驅動控件執行某項功能。

觸發事件的對象稱爲事件發送者;接收事件的對象稱爲事件接收者。

事件就是用戶對窗口上各種組件的操作。

使用事件機制可以實現:當類對象的某個狀態發生變化時,系統將會通過某種途徑調用類中的有關處理這個事件的方法或者觸發控件事件的對象就會調用該控件所有已註冊的事件處理程序等。

在.net框架中,事件是將事件發送者(觸發事件的對象)與事件接受者(處理事件的方法)相關聯的一種代理類,即事件機制是通過代理類來實現的。當一個事件被觸發時,由該事件的代理來通知(調用)處理該事件的相應方法。

C#中事件機制的工作過程如下:

(1)將實際應用中需通過事件機制解決的問題對象註冊到相應的事件處理程序上,表示今後當該對象的狀態發生變化時,該對象有權使用它註冊的事件處理程序。

(2)當事件發生時,觸發事件的對象就會調用該對象所有已註冊的事件處理程序。

什麼是事件驅動?

By the end of 2020, Gartner projects that over 50% of applications will be on EDA.

The Internet of Things, real-time applications, and the sharing economy require “super” distributed processing. This means that cloud servers and edge computing are united seamlessly by an architecture that enables event-driven computing. The existing database architecture has two shortcomings for the Internet of Things systems. First, storage is inflated with endless log data and 99% of data is not used. And second, high latency in data look-up makes real-time computing impossible. Event-Driven Architecture (EDA) addresses these issues.

物聯網、實時應用和共享經濟需要“超級”分佈式處理。這意味着雲服務器和邊緣計算通過一個支持事件驅動計算的架構無縫地結合在一起。物聯網系統現有的數據庫體系結構存在兩個缺陷。首先,無限的日誌數據膨脹了存儲空間,99%的數據沒有被使用。其次,數據查找的高延遲使實時計算變得不可能。事件驅動的體系結構(EDA)解決了這些問題。

What is EDA? EDA is a software architecture that promotes production, detection, processing, and reaction to events. Events can be as varied as a driver picking up a package, a machine measurement hitting a threshold, or a specific customer arriving at a retail outlet. EDA is defined by three properties. First, it selectively transfers relevant events from incoming data to the database. Second, it processes complex events from multiple sources that can impact each other in real-time. And third, it simplifies real-time services with push-type operations. Examples of use cases for event-driven architecture include asset sharing solutions such as DiDi and Uber, prescriptive maintenance systems that allocate maintenance personnel and spare parts, or dynamic customer service applications.

EDA是什麼?EDA是一種軟件體系結構,用於促進事件的生產、檢測、處理和響應。事件可以是多種多樣的,比如一個司機拿起一個包,一個機器測量達到一個閾值,或者一個特定的客戶到達一個零售店。EDA由三個屬性定義。首先,它有選擇地將相關事件從傳入數據傳輸到數據庫。其次,它處理來自多個源的複雜事件,這些事件可以實時地相互影響。第三,它通過推式操作簡化了實時服務。事件驅動架構的用例示例包括滴滴和Uber等資產共享解決方案、分配維護人員和備件的規定維護系統或動態客戶服務應用程序。

說白了,“if A then B”語句中的A 就是 ‘事件’,B就是“響應”。

事件驅動跟消息驅動機制相比

事件驅動和異步IO

通常,我們寫服務器處理模型的程序時,有以下幾種模型:
(1)每收到一個請求,創建一個新的進程,來處理該請求;
(2)每收到一個請求,創建一個新的線程,來處理該請求;
(3)每收到一個請求,放入一個事件列表,讓主進程通過非阻塞I/O方式來處理請求
上面的幾種方式,各有千秋,
第(1)中方法,由於創建新的進程的開銷比較大,所以,會導致服務器性能比較差,但實現比較簡單。
第(2)種方式,由於要涉及到線程的同步,有可能會面臨死鎖等問題。
第(3)種方式,在寫應用程序代碼時,邏輯比前面兩種都複雜。
綜合考慮各方面因素,一般普遍認爲第(3)種方式是大多數網絡服務器採用的方式

在UI編程中,常常要對鼠標點擊進行相應,首先如何獲得鼠標點擊呢?
方式一:創建一個線程,該線程一直循環檢測是否有鼠標點擊,那麼這個方式有以下幾個缺點:

  1. CPU資源浪費,可能鼠標點擊的頻率非常小,但是掃描線程還是會一直循環檢測,這會造成很多的CPU資源浪費;如果掃描鼠標點擊的接口是阻塞的呢?

  2. 如果是堵塞的,又會出現下面這樣的問題,如果我們不但要掃描鼠標點擊,還要掃描鍵盤是否按下,由於掃描鼠標時被堵塞了,那麼可能永遠不會去掃描鍵盤;

  3. 如果一個循環需要掃描的設備非常多,這又會引來響應時間的問題;
    所以,該方式是非常不好的。

方式二:就是事件驅動模型
目前大部分的UI編程都是事件驅動模型,如很多UI平臺都會提供onClick()事件,這個事件就代表鼠標按下事件。事件驅動模型大體思路如下:

  1. 有一個事件(消息)隊列;

  2. 鼠標按下時,往這個隊列中增加一個點擊事件(消息);

  3. 有個循環,不斷從隊列取出事件,根據不同的事件,調用不同的函數,如onClick()、onKeyDown()等;

  4. 事件(消息)一般都各自保存各自的處理函數指針,這樣,每個消息都有獨立的處理函數;

事件驅動架構

事件驅動架構模式是一種非常流行的分佈式異步架構模式,經常被用與構建高可伸縮性的應用程序。當然它也適合小型應用,複雜應用和規模比較大的應用。這種架構模式由一系列高度解耦的、異步接收和處理事件的單一職責的組件所組成。

事件驅動架構由兩個主要的拓撲組成,分別是調停者拓撲和代理者拓撲。調停者拓撲通過一箇中央的調停者來編排各種處理步驟。然而代理者拓撲適用於那些當你想將事件鏈式的聚在一起但不使用中央調停者的情況。由於這兩種模式特性以及實現均不一樣,所以理解哪一個模式最適合你的實際情況是非常重要的。

調停者拓撲

調停者拓撲適合那些有很多步驟需要處理,並且需要按照某種程度的編排來處理的事件。舉個例子,一個處理股票交易的事件首先需要你首先驗證交易的本身合法性,然後檢查這個股票交易是否合規,然後把股票交給股票代理商,計算佣金,然後通過代理商將股票移送給客戶。這些步驟都需要一個編排中心來決定這些步驟的順序,並且決定哪些能是串行的,哪些是並行的。

調停者拓撲主要有4個主要的架構組件組成:事件隊列(Event Queue)、調停者(Mediator)、事件通道(Event Channel)和事件處理器(Event Processor)。

事件流通過客戶端發送到消息隊列,事件隊則傳遞消息到調停者。調停者接收到隊列傳遞過來的原始消息,然後編排成異步的消息發送到事件通道,事件通道則通過事件處理器執行處理過程的每一步。事件處理器則監聽事件通道,根據自身不同的業務邏輯來處理從調停者接受的事件。

If event Then handler,實際上包含三個元素:

1.事件(event);
2.響應(handler);
3.事件與響應的“邏輯關係”

其中的'事件'常常是固定的;而“邏輯關係”往往體現的是業務規則或者核心邏輯,也常常是固定不變的。

只有'響應'是可變的,或者說是可以配置或者需要改變的。

軟件開發的OCP原則告訴我們:“軟件應該對修改關閉,但要對擴展開放”。而事件驅動就是在保持了事件和核心邏輯的穩定性和不被修改的前提下,通過定義不同的“響應”從而達到了對“擴展的開放”。

Event-driven architecture components

An event-driven architecture typically consists of four components:

  1. Event
    The significant change in the state of an object that occurs when users take action.

  2. Event Handler
    A software routine, which handles the occurrence of an event.

  3. Event Loop
    Event loop handles the flow of interaction between an event and the event handler.

  4. Event Flow Layers
    The event flow layer is built on three logical layers: Event Producer, Event Consumer, and Event Channel (also called Event Bus).

Producer which is responsible for detecting and generating events.

Consumer which consumes the events produced by the event producer.

Event Channel which transfers events from the event generator to the event consumer.

關於最終一致性

響應事件而不是“及時”查詢權限系統會讓我們更具有自主性,更有容錯能力和彈性,但也有一點其他影響,會影響自治事件驅動系統的是“延遲”。

如果你立即注意到某一事件,你可以立即做出反應。例如,如果一輛車轉彎進入你的車道,你看到這個,你可以很快剎車或者調整駕駛避免不發生碰撞。但是,如果有一些延遲,在觀察到這個事件後,你的反應可能是緩慢的(也許有駕駛障礙?或者你在玩手機?或是在你的孩子們做某事,等等)。

這也可能發生在IT系統。比如在亞馬遜訂購商品。這會對其他自主服務(如訂單處理,帳單,庫存等)發佈一個事件或事實。這些系統可以觀察到這一事件,但如果此時庫存系統從網絡斷開幾分鐘/小時?當他們重新恢復正常運行後,他們最終會看到這個事件並繼續檢查庫存,發佈任何它認爲必要的事件(即反應)像“inventoryreserved事件”或“inadequateinventory”事件。這是一組自主系統“最終”變得一致的一個簡單例子。

最後一件事是關於事件,延遲和自主權。如果我們能夠捕捉到它們並觀察它們的順序,事件就是有用的。也就是說,在我們的系統中必須保留一組事件的總排序,這樣我們才能如何對它們做出反應有信心。

現在你已經明白:事件的順序在分佈式系統中構建事務是如何的重要,如果事件變得無序,那麼我們就無從獲得最終一致性,除非再次需要人工介入。

小結

Event-Driven Architecture

Domain Events 領域事件
Event Sourcing
Command and Query Responsibility CQRS
Segregation (CQRS) pattern

Event Stream Processing 簡稱ESP
Messaging 消息系統
Enterprise Service Bus ESB總線
Actors
Enterprise Integration Architecture (EIA)
Event Sourcing事件溯源

每個狀態的改變都可以表達爲事件。事件觸發狀態改變。
所有的事件被髮往EventProcessor
EventProcessor 將所有事件保存在 Event Log
系統能夠被複位,這樣Event Log 會重播。
不再需要ORM, 只要持久化Events。
很多不同的EventListeners被加到EventProcessor,對其監聽(or listen directly on the Event log)

CQRS特點

所有狀態改變由Domain Events驅動
聚合根接受 Commands,然後發佈 Events
報表系統 (數據庫查詢) 將作爲一個發佈後事件published Events的結果
所有來自表現層查詢直接走報表系統。

CQRS優點

充分封裝了業務領域,只暴露行爲。
查詢不使用 domain model
沒有對象和關係不匹配問題。
易於跟蹤審計和歷史
易於和外部系統整合。
性能與可伸縮性。

參考資料

https://www.softobiz.com/understanding-the-event-driven-architecture/
https://medium.com/@prashunjaveri/architectural-patterns-for-iot-event-driven-architectures-557be35fa626
https://www.eda-consortium.cn/abouteventdrivenarchitecture
https://www.jdon.com/artichect/scalable8.html


Kotlin開發者社區

專注分享 Java、 Kotlin、Spring/Spring Boot、MySQL、redis、neo4j、NoSQL、Android、JavaScript、React、Node、函數式編程、編程思想、"高可用,高性能,高實時"大型分佈式系統架構設計主題。

High availability, high performance, high real-time large-scale distributed system architecture design

分佈式框架:Zookeeper、分佈式中間件框架等
分佈式存儲:GridFS、FastDFS、TFS、MemCache、redis等
分佈式數據庫:Cobar、tddl、Amoeba、Mycat
雲計算、大數據、AI算法
虛擬化、雲原生技術
分佈式計算框架:MapReduce、Hadoop、Storm、Flink等
分佈式通信機制:Dubbo、RPC調用、共享遠程數據、消息隊列等
消息隊列MQ:Kafka、MetaQ,RocketMQ
怎樣打造高可用系統:基於硬件、軟件中間件、系統架構等一些典型方案的實現:HAProxy、基於Corosync+Pacemaker的高可用集羣套件中間件系統
Mycat架構分佈式演進
大數據Join背後的難題:數據、網絡、內存和計算能力的矛盾和調和
Java分佈式系統中的高性能難題:AIO,NIO,Netty還是自己開發框架?
高性能事件派發機制:線程池模型、Disruptor模型等等。。。

合抱之木,生於毫末;九層之臺,起於壘土;千里之行,始於足下。不積跬步,無以至千里;不積小流,無以成江河。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章