經過對多個有關事件總線模式的文檔介紹的閱讀,對事件總線模式有了一定的了解,並作出如下總結:
一、 事件總線模式主要是處理事件,包括4個主要組件:事件源、事件監聽器、通道和事件總線。消息源將消息發布到事件總線上的特定通道上。偵聽器訂閱特定的通道。偵聽器會被通知消息,這些消息被發布到它們之前訂閱的一個通道上。
使用場景:安卓開發、通知服務
優點:新的發布者、訂閱者和連接可以很容易地添加。對高度分布式的應用程序有效。
缺點:可伸縮性可能是一個問題,因為所有消息都是通過同一事件總線進行的。
二、基於事件驅動的分布式異步架構模式多用於構建高可伸縮的反應式應用程序,適用於各種從簡單到復雜的應用場景。它的核心思想是去耦合,將消息的發送和接收分開,實現異步處理消息事件。
事件總線是實現基於事件驅動模式的方式之一,或者可以將其稱為“Broker Topology”。事件發送者將事件消息發送到一個中心 broker 上,事件訂閱者向中心 broker 訂閱和接收事件,然后再處理接收到的事件。當然,訂閱者不僅可以接收和消費事件,它們本身也可以創建事件,並將它們發送到事件總線上。下面列出了 4 種事件總線的實現方式,並對它們的優缺點進行了總結。
1. 向所有的訂閱者發送事件
事件總線直接將輸入事件(紅色箭頭)發送給訂閱者(藍色方塊)
參與者
事件總線、訂閱者(事件處理器)、事件創建者
實現
事件創建者向事件總線發送事件,事件總線將收到的事件發送給所有的訂閱者。訂閱者既可以處理接收到的事件,也可以創建新事件,然后把它們發送給事件總線。事件總線不關心訂閱者是否成功接收到消息。
功能需求
通知、訂閱、退訂。
優勢
實現起來很簡單。
不足
事件總線需要將每一個事件消息復制一份給訂閱者,也就是說,如果有1000個訂閱者,每一個事件都會有1000份拷貝,這樣會占用大量的內存。
事件總線不保證消息傳遞的可靠性,它會嘗試給訂閱者發送消息,而且只會嘗試一次,如果出現錯誤,比如網絡連接錯誤,訂閱者可能就會收不到消息。
另外,事件總線不負責過濾消息,所以訂閱者需要自己實現過濾邏輯。
2. 向所有訂閱者發送事件影子
事件總線和事件存儲及事件觀察者
參與者
事件總線、事件創建者、訂閱者、事件存儲(Event Store)、事件觀察者(Event Watcher)
實現
事件總線在收到事件創建者發送過來的事件后,把事件保存到事件存儲里,然后將事件影子(Event Shadow,也就是對原始事件的引用)發送給所有的訂閱者。訂閱者根據事件影子從事件存儲里獲取事件數據,再對數據進行處理。
事件總線為每一個事件創建一個事件觀察者,觀察者持有訂閱者列表,當所有的訂閱者都接收到消息后,觀察者負責把事件從事件存儲里刪除。
事件總線仍然不保證訂閱者一定會收到所有事件影子。如果有訂閱者接收消息失敗,相應的觀察者就會被標記為“skipped”。
功能需求
通知、訂閱、退訂、保存/刪除/獲取、標記完成/跳過
優勢
因為事件消息被保存在事件存儲里,發送給訂閱者的只是事件引用,所以占用內存會小很多。
不足
訂閱者需要調用額外的方法,比如在收到事件影子之后要調用方法去獲取事件數據,在處理完事件后還要調用方法通知事件總線已完成處理,或者通知事件總線跳過某個事件。另外,在事件總線端還要實現事件存儲和事件觀察者。這個對事件存儲的實現要求比較高,如果訂閱者數量很多,事件存儲的讀負載會很重,而且在寫入事件時是阻塞式的。
這種實現方式仍然不會為訂閱者過濾事件,所以訂閱者還是需要自己實現事件過濾。
3. 向經過過濾的訂閱者發送事件影子
第三種實現方式與第二種是一樣的,只不過不是將事件影子發送給所有訂閱者,而是發送給經過過濾的訂閱者,也就是說只發送給其中的一部分訂閱者。事件總線需要記錄訂閱者感興趣的主題,在這里可以使用正則過濾器為訂閱者過濾主題。
這種方式的優勢與不足和第二種也是一樣的,只是多了事件過濾功能。
4. 按順序傳遞
為了保證順序傳遞,可以對事件進行分區。關於如何通過分區來保證順序傳遞,可以參考Kafka的論文,基本原理是讓消費者消費屬於自己的分區。
不足
動態增加分區或減少分區會變得很困難,而且需要自己實現分區器,消費者的實現也很復雜。