首頁  >  文章  >  Java  >  基於Java的分散式服務框架Dubbo的原理及範例分析

基於Java的分散式服務框架Dubbo的原理及範例分析

王林
王林轉載
2023-04-24 20:13:061101瀏覽

    前言

    在介紹Dubbo之前先了解基本概念:

    Dubbo是一個RPC框架, RPC,即Remote Procedure Call(遠端過程調用),相對的就是本地過程調用,在分散式架構之前的單體應用架構和垂直應用架構運用的都是本地過程調用。它允許程式呼叫另一個位址空間(通常是網路共享的另一台機器)的過程或函數,並且不用程式設計師明確編碼這個遠端呼叫的細節。

    而分散式架構應用與應用程式之間的遠端呼叫就需要RPC框架來做,目的就是為了讓遠端呼叫像本地呼叫一樣簡單。

    基於Java的分散式服務框架Dubbo的原理及範例分析

    Dubbo框架有以下部件

    Consumer

    即呼叫遠端服務的服務消費方,消費者需要面向介面編程,並知道了哪些接口可以呼叫了,具體實現需要框架提供一個代理類來為接口提供具體實現,讓消費者只管調用什麼接口,而具體實現的獲取由代理類來處理。

    消費者還需要提供呼叫方法名稱以及方法的參數值。

    但是代理程式類別此時還不知道需要呼叫哪個伺服器上的遠端方法,此時需要一個註冊中心,透過註冊中心取得可以呼叫的遠端服務清單。

    遠端伺服器一般都是叢集部署,那麼呼叫哪個伺服器則需要透過負載平衡來選擇一個最適合的伺服器來呼叫。

    同時也需要有叢集容錯機制,因為各種原因,可能遠端調用會失敗,此時需要容錯機制來重試調用,確保遠端調用的穩定性。

    同時與服務提供者約定好通訊協定和序列化格式,方便通訊以及資料傳輸。

    Provider

    即暴露服務的服務提供方,服務提供者內部實現具體的接口,然後將接口暴露出去,再將服務註冊到註冊中心,服務消費方調用服務,提供者接收到呼叫請求後,透過約定好的通訊協定來處理該請求,然後做反序列化,完成後,將請求放入線程池中處理,某個執行緒接收到這個請求然後找到對應的介面實現進行調用,然後將調用結果原路返回。

    Registry

    即服務註冊與發現的註冊中心,註冊中心負責服務地址的註冊與查找,相當於服務目錄,服務提供者和消費者只會再啟動時與註冊中心交互,註冊中心不轉發請求,壓力小。

    基於Java的分散式服務框架Dubbo的原理及範例分析

    註冊中心還可以集中化處理配置以及動態地將變更通知訂閱方。

    但是為什麼需要註冊中心呢?沒有註冊中心不可以嗎?

    在沒有註冊中心,各服務之間的呼叫關係是這樣的:

    基於Java的分散式服務框架Dubbo的原理及範例分析

    當服務越來越多時,服務URL組態管理變得非常困難,硬體負載平衡器的單點壓力也越來越大,而有了註冊中心之後,就可以實現服務的統一管理,並且實現軟負載平衡,降低硬體成本,以下為註冊中心示意圖:

    基於Java的分散式服務框架Dubbo的原理及範例分析

    Monitor

    即統計服務呼叫次數和呼叫時間的監控中心,面對眾多服務,精細化的監控和方便的運維是不可或缺的,對後期維護相當重要。

    Container

    即服務運行的容器。

    架構

    基於Java的分散式服務框架Dubbo的原理及範例分析

    圖中的各個節點扮演的角色已經介紹過了,以下是各節點之間呼叫關係:

    #Container服務容器負責啟動,載入以及執行

    Provider服務提供者Provider服務提供者啟動時,需要將自身暴露出去讓遠端伺服器可以發現,同時向Registry註冊中心註冊自己提供的服務

    #Consumer服務消費者啟動時,向Registry註冊中心訂閱所需的服務

    Registry註冊中心返回服務提供者清單給消費者,同時如果發生變更,註冊中心將基於長連接推送即時資料給消費者

    服務消費者需要調用遠端服務時,會從提供者的位址清單中,基於負載平衡演算法選出一台提供者伺服器進行調用,如果調用失敗,會基於叢集容錯策略進行調用重試

    服務消費者與提供者會在記憶體中統計呼叫次數和呼叫時間,然後透過定時任務將資料傳送給Monitor監控中心

    高可用性

    • 監控中心宕機後不會對服務造成影響,只是遺失部分統計資料

    • 註冊中心叢集後,任一台宕機後,將自動切換到其他註冊中心

    • 當所有註冊中心均宕機後,服務提供者和消費者之間仍然能透過本地記錄了彼此資訊的快取進行通訊,但是如果一方產生變更,另外一方無法感知

    • 服務提供者無狀態,任一台伺服器當機後不影響使用,會有其他服務提供者提供服務

    • 當所有服務提供者宕機後,服務消費者無法正常使用,將進行無限次重連等待服務提供者重新連線恢復

    框架設計

    基於Java的分散式服務框架Dubbo的原理及範例分析

    大的分層為Business(業務邏輯層)、RPC層和Remoting層。

    再細分下來,Dubbo一共有十層架構,作用分別如下:

    Service,業務層,即日常開發中的業務邏輯層

    Config,配置層,對外配置接口,以ServiceConfigReferenceConfig為中心,可以直接初始化配置類,也可以透過Spring解析配置生成配置類別

    Proxy,服務代理層,服務介面透明代理,生成服務的客戶端Stub和客戶端Skeleton,負責遠端呼叫與傳回結果

    Registry,註冊中心層,封裝服務地址的註冊與發現,以服務URL為中心,拓展介面為RegistryFactory RegistryRegistryService

    Cluster#路由和叢集容錯層,封裝了多個提供者的路由、負載平衡以及叢集容錯,並橋接註冊中心,負責透過負載平衡選取呼叫特定的節點,處理特殊呼叫請求和負責遠端呼叫失敗的容錯措施

    Monitor,監控層,負責監控統計RPC呼叫次數和呼叫時間

    Portocol,遠端呼叫層,主要封裝RPC遠端呼叫方法

    #Exchange,資訊交換層,用於封裝請求回應模型

    Transport,網路傳輸層,抽象網路傳輸統一接口,有MinaNetty可使用

    Serialize,序列化層,將資料序列化成二進位流進行傳輸,也可以反序列化接收資料

    服務暴露過程

    首先Provider啟動,Protocal透過Proxy代理將需要暴露的介面封裝成Invoker,是一個可執行體,然後透過Exporter包裝並送到註冊中心完成註冊,至此服務就暴露完成。

    基於Java的分散式服務框架Dubbo的原理及範例分析

    服務消費流程

    基於Java的分散式服務框架Dubbo的原理及範例分析

    #註:上圖中藍色部分為服務消費者,綠色部分為服務提供者。

    服務消費者啟動時會向註冊中心訂閱並拉取所需服務提供者的信息,並保存到本地緩存,由此即使所有註冊中心宕機後,服務提供者和服務消費者也可以透過本地快取進行通訊,只是一方出現了資訊變更,另一方無法感知,但不影響服務的進行。

    之後整個服務消費流程從圖中的Proxy開始,由代理類別完成處理,以此到達透明無感知。

    ProxyFactory產生一個Proxy代理類,Proxy持有一個Invoker可執行對象,呼叫invoke之後需要透過ClusterDirectory中取得所有可呼叫的遠端服務Invoker列表,如果配置了某些路由規則,則需要再過濾一次Invoker列表。

    剩下的Invoker再透過LoadBalance做負載平衡選取一個,還需要再透過Filter進行一些資料統計,之後將這些資料保存下來,定時傳送給Monitor

    接下來用Client做資料傳輸,一般用Netty傳輸。

    傳輸需要透過Codec介面進行協定構造,然後再透過Serialization進行序列化,最後將序列化後的二進位流傳送至給對應的服務提供者。

    服務提供者接收到二進位流後也會進行Codec協定處理,然後進行反序列化(此處的處理與傳輸之前的處理是呈對稱的)後將請求放入線程池中處理,某個執行緒會根據請求找到對應的Exporter,然後再透過Filter進行層層過濾得到Invoker,最後呼叫對應的實作類別然後將結果原路回傳。

    以上是基於Java的分散式服務框架Dubbo的原理及範例分析的詳細內容。更多資訊請關注PHP中文網其他相關文章!

    陳述:
    本文轉載於:yisu.com。如有侵權,請聯絡admin@php.cn刪除