RSF 分佈式服務框架設計:線程模型

RSF 的線程模型

    使用了 RSF 框架以後系統一共會產生至少 7 條線程,有些功能的線程可能會產生多個。咱們先來鳥瞰一下全部的線程和它們的大體功能。java

    初一看,還真是挺複雜的,這麼多線程,這麼多功能。根據重要程度大體能夠分爲這麼兩類。git

    主要線程:監聽線程、定時器線程、網絡IO線程、RPC調用線程
    次要線程:地址本備份線程、Telnet線程、Hasor事件異步處理線程github

    其中主要線程中能夠進一步在分爲核心線程和重要線程。它們是:網絡

    核心線程:監聽線程、網絡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 調用線程去處理。ide

     「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/rsf or https://github.com/zycgit/rsf
RSF系列文章:https://my.oschina.net/u/1166271/blog?catalog=574765&temp=1477997059095

相關文章
相關標籤/搜索