[從原始碼學設計]螞蟻金服SOFARegistry之訊息匯流排
阿新 • • 發佈:2020-12-02
# [從原始碼學設計]螞蟻金服SOFARegistry之訊息匯流排
[toc]
## 0x00 摘要
SOFARegistry 是螞蟻金服開源的一個生產級、高時效、高可用的服務註冊中心。
本系列文章重點在於分析設計和架構,即利用多篇文章,從多個角度反推總結 DataServer 或者 SOFARegistry 的實現機制和架構思路,讓大家藉以學習阿里如何設計。
本文為第四篇,介紹SOFARegistry之訊息匯流排。
## 0x01 相關概念
### 1.1 事件驅動模型
事件驅動模型,也即是我們通常說的觀察者。基於釋出-訂閱模式的程式設計模型。
#### 1.1.1 概念
定義物件間的一種一對多的依賴關係,當一個物件的狀態發生變化時,所有依賴它的物件都得到通知並自動更新。
從程式設計的角度來看,事件驅動模型的核心構件通常包含以下幾個:
- 事件源:負責產生事件的物件。比如我們常見的按鈕,按鈕就是一個事件源,能夠產生“點選”這個事件
- 事件監聽器(事件處理器):負責處理事件的物件
- 事件:或者稱為事件物件,是事件源和事件監聽器之間的資訊橋樑。是整個事件模型驅動的核心
#### 1.1.2 應用環境
當我們面對如下的環境時,事件驅動模型通常是一個好的選擇:
- 程式中有許多工;
- 任務之間高度獨立(因此它們不需要互相通訊,或者等待彼此);
- 在等待事件到來時,某些任務會阻塞;
### 1.2 訊息匯流排
匯流排(Bus)一般指計算機各種功能部件之間傳送資訊的公共通訊幹線,而EventBus則是事件源(publisher)向訂閱方(subscriber)傳送訂閱事件的匯流排,它解耦了觀察者模式中訂閱方和事件源之間的強依賴關係。
訊息匯流排扮演著一種**訊息路由**的角色,擁有一套完備的路由機制來決定**訊息傳輸**方向。傳送端只需要向訊息匯流排發出訊息而不用管訊息被如何轉發,為了**避免訊息丟失**,部分訊息匯流排提供了一定的**持久化儲存和災備的機制**。
訊息匯流排簡單理解就是一個訊息中心,眾多微服務例項可以連線到總線上,例項可以往訊息中心傳送或接收資訊(通過監聽)。
一般的應用的場景就是在用觀察者模式的地方就可以用EventBus進行替代。
![img](https://img2018.cnblogs.com/blog/1318007/201812/1318007-20181227231253239-1564153018.png)
## 0x02 業務領域
### 2.1 業務範疇
DataServer 本質上是一個網路應用程式,所以有如下特點:
- 需要處理各個方面傳送來的訊息;
- 程式中任務繁多,任務之間獨立,大多數任務不存在互斥通訊等操作;在等待事件到來時,某些任務會阻塞;
- 某一個訊息往往有多個投遞源;
因此天然適合用事件驅動機制來實現。
### 2.2 問題點
能夠想到的問題點如下:
- 因為一個事件往往會有多個投遞源,如何解耦事件投遞和事件處理之間的邏輯?
- 怎樣實現Listener一次註冊,就能夠知道Listener對那些事件感興趣的,進而在有某類事件發生時通知到Listener的呢?
- 如何使得一個Listener可以處理多個事件?
- 如何使得一個事件被多個Listener處理?
- 可否簡化註冊流程?
- 是否需要維護訊息順序?
- 處理訊息方式是非同步還是同步?
- 多個同樣訊息是否要歸併?
具體我們在後文會詳述阿里的思路。
### 2.3 解決方案
DataServer 內部邏輯主要是通過事件驅動機制來實現的,下圖列舉了部分事件在事件中心的互動流程,從圖中可以看到,一個事件往往會有多個投遞源 ,非常適合用 EventCenter 來解耦事件投遞和事件處理之間的邏輯;
![](https://img2020.cnblogs.com/blog/1850883/202011/1850883-20201129214348662-1377207449.png)
## 0x03 EventCenter
業界訊息匯流排有很多,比如 Android EventBus是一個**釋出/訂閱事件**匯流排框架,基於觀察者模式,將事件的接收者和傳送者分開,簡化了元件之間的通訊。
而SOFARegistry EventCenter 的作用也類似:從邏輯上解耦,將事件的接收者和傳送者分開,簡化元件之間通訊。阿里的實現有自己的特點,開發者可以借鑑這裡的使用技巧和思路。
### 3.1 目錄結構
```java
├── event
│ ├── AfterWorkingProcess.java
│ ├── DataServerChangeEvent.java
│ ├── Event.java
│ ├── EventCenter.java
│ ├── LocalDataServerChangeEvent.java
│ ├── MetaServerChangeEvent.java
│ ├── RemoteDataServerChangeEvent.java
│ ├── StartTaskEvent.java
│ ├── StartTaskTypeEnum.java
│ └── handler
│ ├── AbstractEventHandler.java
│ ├── AfterWorkingProcessHandler.java
│ ├── DataServerChangeEventHandler.java
│ ├── LocalDataServerChangeEventHandler.java
│ ├── MetaServerChangeEventHandler.java
│ └── StartTaskEventHandler.java
```
### 3.2 類定義
類定義如下:
```java
public class EventCenter {
private