1. 程式人生 > 實用技巧 >RSF 分散式服務框架設計:執行緒模型

RSF 分散式服務框架設計:執行緒模型

>>> hot3.png

RSF 的執行緒模型

使用了 RSF 框架之後系統一共會產生至少 7 條執行緒,有些功能的執行緒可能會產生多個。我們先來鳥瞰一下所有的執行緒和它們的大致功能。

初一看,還真是挺複雜的,這麼多執行緒,這麼多功能。根據重要程度大致可以分為這麼兩類。

主要執行緒:監聽執行緒、定時器執行緒、網路IO執行緒、RPC呼叫執行緒
次要執行緒:地址本備份執行緒、Telnet執行緒、Hasor事件非同步處理執行緒

其中主要執行緒中可以進一步在分為核心執行緒和重要執行緒。它們是:

核心執行緒:監聽執行緒、網路IO執行緒、RPC呼叫執行緒。
重要執行緒:定時器執行緒。

核心執行緒

現在我們就從最最重要的核心執行緒說起,然後在談一談同樣重要的定時器執行緒。先看一張圖直觀的感受一下 RSF 的執行緒模型。

網路部分(RSF-Nio):

在 RSF 中 監聽執行緒 的作用就是接受 遠端計算機的連線請求,並負責建立 Socket 通訊通道。因為RSF 採用了長連結雙向通訊的工作模式。因此一般兩臺計算機在順利連結上之後短時間內不會關閉彼此的連結。因此一般情況下 1 條執行緒足以應付。

其次就是 RSF 的 網路IO執行緒 這個執行緒的主要目的是負責處理網路 IO 的讀寫操作。可以說網路IO執行緒 處理了所有 RSF 網路相關資料的傳輸操作。

監聽執行緒 和 IO 執行緒是由 Netty 的“io.netty.channel.nio.NioEventLoopGroup”類提供支援。下面是 RSF 中框架啟動的程式碼節選,圖中紅框部分就是 監聽執行緒和網路IO執行緒的使用。 它和一般情況下 Netty 啟動 TCP 監聽的方式是一樣的。這段程式碼位於“net.hasor.rsf.rpc.net.RsfNetManager”類的“start”方法中。有興趣的同學可以去看一看 RSF 的網路啟動過程。

Server 在啟動之後開始源源不斷的從網路上非同步的接受 RSF request 請求。然後再把接收到的網路資料經過協議層轉換為 RsfRequest 物件,然後在丟入RPC佇列。最後交給 RPC 呼叫執行緒去處理。

“net.hasor.rsf.rpc.net.RpcCodec”類就是負責接收 RSF 網路資料然後通過“net.hasor.rsf.rpc.net.ReceivedListener”介面送到佇列中。下面紅框部分就是實現訊息接收並通過“ReceivedListener”介面丟入佇列的程式碼。

上面程式碼中的shakeHands 表示通訊是否已經通過握手。有關 RSF 握手協議在後面我會在專門的 Blog 文章中進行講解。

最後在“net.hasor.rsf.rpc.caller.remote.RemoteRsfCaller”類中 RSF 會負責接收“ReceivedListener”介面丟過來的 Request物件並放入佇列。

這裡把“ReceivedListener”介面設計成中轉站的目的是是為了實現“網路通訊層”和“RPC呼叫層”之間的解耦。最後整體架構上就會變成我們預想的樣子。

RPC呼叫部分(RSF-Biz)

在上面網路部分,我們已經知道網路 IO 執行緒的工作原理,現在我們在來看看負責處理RPC呼叫部分的 work 執行緒是如何工作的。

首先這裡的 work 指的不是 Netty 層面上的 Work 執行緒。Netty 層面上的 Work 執行緒對應的是我們剛剛討論的 網路 IO 執行緒(RSF-Nio)。我們這裡即將討論的 work 執行緒是專門用來處理 RPC 呼叫的執行緒(RSF-Biz)。

RSF-Biz 的執行緒入口類是“net.hasor.rsf.rpc.caller.remote.RemoteRsfCallerProcessing”,每當網路 IO 執行緒收到 Request 之後都會建立一個“RemoteRsfCallerProcessing”物件並將這個物件扔到“Executor”裡面,具體為 java 自帶的併發框架“java.util.concurrent.Executor”。

由於“Executor”是一個有序的佇列。因此在真正執行“RemoteRsfCallerProcessing”的時候,我們並不知道這個Rsf Request從進入佇列到它執行期間一共等待了多久。因此在“RemoteRsfCallerProcessing”正式處理呼叫之前先要做的就是判斷是否超時、要呼叫的服務是否存在等等檢測,最後執行“Method.invoke” 執行呼叫。返回結果。

為了簡單的說明 RSF “RemoteRsfCallerProcessing”都做了哪些事我把程式碼的執行流程簡要列一下:

  1. 正確性檢驗
  2. 檢查timeout
  3. 準備引數
  4. 執行呼叫
  5. 將Response寫入客戶端

其中正確性校驗會檢查本地是否註冊 RsfBindInfo,如果有註冊是否為服務提供者(Provider)。而 timeout 檢測會判斷當前時間和資料包接收時間之間是否超過規定時間,如果超過規定時間也放棄不在執行。

這裡最有必要說一下的就是“準備引數”這個環節,在 RSF 中引數的反序列化和引數個數校驗都在這裡進行。換句話說 RSF 的 IO執行緒並不負責處理序列化和反序列化,而是交給了業務執行執行緒。下面是引數反序列化的程式碼。

然後在最後部分,RSF 還沒有忘記服務端的 RsfFilter擴充套件機制實現。

有興趣的同學可以去分析 RSF 的原始碼,這裡就不在逐個展開說明,接下來我們來說一下主要執行緒中唯一沒有討論到的“定時器執行緒”。

重要執行緒

這個執行緒用一句話來概括就是乾的活比較雜,例如:當 RSF 請求發出之後,會啟動一個對應的 Timer。Timer的目的是用來處理,請求發出之後過了很久都沒有 Respnse 回來的情形。遇到這種情形,Timer 超時的時候就會自己寫入一個 Timout 異常。

這段邏輯位於“net.hasor.rsf.rpc.caller.RsfRequestManager”類中“startRequest”方法。有興趣的同學可以去看 RSF 程式碼。

專案介紹:https://www.oschina.net/p/Hasor-RSF
原始碼位置:http://git.oschina.net/zycgit/rsforhttps://github.com/zycgit/rsf
RSF系列文章:https://my.oschina.net/u/1166271/blog?catalog=574765&temp=1477997059095

轉載於:https://my.oschina.net/ta8210/blog/779361