?
Dubbo
前言
在介紹Dubbo之前先了解一下基本概念:
Dubbo是一個RPC框架,RPC,即Remote Procedure Call(遠程程序呼叫),相對的就是本地程序呼叫,在分布式架構之前的單體應用架構和垂直應該架構運用的都是本地程序呼叫,它允許程式呼叫另外一個地址空間(通常是網路共享的另外一臺機器)的程序或函式,并且不用程式員顯式編碼這個遠程呼叫的細節,
而分布式架構應用與應用之間的遠程呼叫就需要RPC框架來做,目的就是為了讓遠程呼叫像本地呼叫一樣簡單,

Dubbo框架有以下部件:
Consumer
即呼叫遠程服務的服務消費方,消費者需要面向介面編程,知道了哪些介面可以呼叫了,具體實作需要框架提供一個代理類來為介面提供具體實作,讓消費者只管呼叫什么介面,而具體實作的獲取由代理類來處理,
消費者還需要提供呼叫方法名以及方法的引數值,
但是代理類此時還不知道需要呼叫哪個服務器上的遠程方法,此時需要一個注冊中心,通過注冊中心獲取可以呼叫的遠程服務串列,
遠程服務器一般都是集群部署,那么呼叫哪個服務器則需要通過負載均衡來選擇一個最合適的服務器來呼叫,
同時還需要有集群容錯機制,因為各種原因,可能遠程呼叫會失敗,此時需要容錯機制來重試呼叫,保證遠程呼叫的穩定性,
同時與服務提供方約定好通信協議和序列化格式,方便通信以及資料傳輸,
Provider
即暴露服務的服務提供方,服務提供方內部實作具體的介面,然后將介面暴露出去,再將服務注冊到注冊中心,服務消費方呼叫服務,提供者接收到呼叫請求后,通過約定好的通信協議來處理該請求,然后做反序列化,完成后,將請求放入執行緒池中處理,某個執行緒接收到這個請求然后找到對應的介面實作進行呼叫,然后將呼叫結果原路回傳,
Registry
即服務注冊與發現的注冊中心,注冊中心負責服務地址的注冊與查找,相當于服務目錄,服務提供者和消費者只會再啟動時與注冊中心互動,注冊中心不轉發請求,壓力小,

注冊中心還可以集中化處理配置以及動態地將變更通知訂閱方,
但是為什么需要注冊中心呢?沒有注冊中心不可以嗎?
在沒有注冊中心,各服務之間的呼叫關系是這樣的:

當服務越來越多時,服務URL配置管理變得非常困難,硬體負載均衡器的單點壓力也越來越大,而有了注冊中心之后,就可以實作服務的統一管理,并且實作軟負載均衡,降低硬體成本,以下為注冊中心示意圖:

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

圖中的各個節點充當的角色已經介紹過了,以下是各節點之間呼叫關系:
Container服務容器負責啟動,加載以及運行Provider服務提供者Provider服務提供者啟動時,需要將自身暴露出去讓遠程服務器可以發現,同時向Registry注冊中心注冊自己提供的服務Consumer服務消費者啟動時,向Registry注冊中心訂閱所需要的服務Registry注冊中心回傳服務提供者串列給消費者,同時如果發生變更,注冊中心將基于長連接推送實時資料給消費者- 服務消費者需要呼叫遠程服務時,會從提供者的地址串列中,基于負載均衡演算法選出一臺提供者服務器進行呼叫,如果呼叫失敗,會基于集群容錯策略進行呼叫重試
- 服務消費者與提供者會在記憶體中統計呼叫次數和呼叫時間,然后通過定時任務將資料發送給
Monitor監控中心
高可用性
- 監控中心宕機后不會對服務造成影響,只是丟失部分統計資料
- 注冊中心集群后,任意一臺宕機后,將自動切換到其他注冊中心
- 當所有注冊中心均宕機后,服務提供者和消費者之間仍然能通過本地記錄了彼此資訊的快取進行通訊,但是如果一方產生變更,另外一方無法感知
- 服務提供者無狀態,任意一臺服務器宕機后不影響使用,會有其他服務提供者提供服務
- 當所有服務提供者宕機后,服務消費者無法正常使用,將進行無限次重連等待服務提供者重新連線恢復
框架設計

大的分層為Business(業務邏輯層)、RPC層和Remoting層,
再細分下來,Dubbo一共有十層架構,作用分別如下:
Service,業務層,即日常開發中的業務邏輯層Config,配置層,對外配置介面,以ServiceConfig和ReferenceConfig為中心,可以直接初始化配置類,也可以通過Spring決議配置生成配置類Proxy,服務代理層,服務介面透明代理,生成服務的客戶端Stub和客戶端Skeleton,負責遠程呼叫和回傳結果Registry,注冊中心層,封裝服務地址的注冊與發現,以服務URL為中心,拓展介面為RegistryFactory,Registry,RegistryServiceCluster路由和集群容錯層,封裝了多個提供者的路由、負載均衡以及集群容錯,并橋接注冊中心,負責通過負載均衡選取呼叫具體的節點,處理特殊呼叫請求和負責遠程呼叫失敗的容錯措施Monitor,監控層,負責監控統計RPC呼叫次數和呼叫時間Portocol,遠程呼叫層,主要封裝RPC遠程呼叫方法Exchange,資訊交換層,用于封裝請求回應模型Transport,網路傳輸層,抽象化網路傳輸統一介面,有Mina和Netty可供使用Serialize,序列化層,將資料序列化成二進制流進行傳輸,也可以反序列化接收資料
服務暴露程序
首先Provider啟動,Protocal通過Proxy代理將需要暴露的介面封裝成Invoker,是一個可執行體,然后通過Exporter包裝并發送到注冊中心完成注冊,至此服務就暴露完成,

服務消費程序

注:上圖中藍色部分為服務消費者,綠色部分為服務提供者,
服務消費者啟動時會向注冊中心訂閱并拉取所需服務提供者的資訊,并保存到本地快取,由此即使所有注冊中心宕機后,服務提供者和服務消費者也可以通過本地快取進行通訊,只是一方出現了資訊變更,另一方無法感知,但并不影響服務的進行,
之后整個服務消費流程從圖中的Proxy開始,由代理類完成處理,以此到達透明無感知,
ProxyFactory生成一個Proxy代理類,Proxy持有一個Invoker可執行物件,呼叫invoke之后需要通過Cluster從Directory中獲取所有可呼叫的遠程服務Invoker串列,如果配置了某些路由規則,還需要再過濾一遍Invoker串列,
剩下的Invoker再通過LoadBalance做負載均衡選取一個,還需要再通過Filter進行一些資料統計,之后將這些資料保存下來,定時發送給Monitor,
接下來用Client做資料傳輸,一般用Netty進行傳輸,
傳輸需要通過Codec介面進行協議構造,然后再通過Serialization進行序列化,最后將序列化后的二進制流發送至給對應的服務提供者,
<=分割線=>
服務提供者接收到二進制流后也會進行Codec協議處理,然后進行反序列化(此處的處理與傳輸之前的處理是呈對稱的)后將請求放入執行緒池中處理,某個執行緒會根據請求找到對應的Exporter,然后再通過Filter進行層層過濾得到Invoker,最終呼叫對應的實作類然后將結果原路回傳,
以上,
整理不易,如果對你有幫助請留個三連吧!
如有錯誤或不足歡迎評論指正,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/300997.html
標籤:其他
