您好,登錄后才能下訂單哦!
這篇文章給大家分享的是有關java開發分布式服務框架Dubbo原理機制的示例分析的內容。小編覺得挺實用的,因此分享給大家做個參考,一起跟隨小編過來看看吧。
在介紹Dubbo之前先了解一下基本概念:
Dubbo是一個RPC
框架,RPC
,即Remote Procedure Call
(遠程過程調用),相對的就是本地過程調用,在分布式架構之前的單體應用架構和垂直應用架構運用的都是本地過程調用。它允許程序調用另外一個地址空間(通常是網絡共享的另外一臺機器)的過程或函數,并且不用程序員顯式編碼這個遠程調用的細節。
而分布式架構應用與應用之間的遠程調用就需要RPC
框架來做,目的就是為了讓遠程調用像本地調用一樣簡單。
即調用遠程服務的服務消費方,消費者需要面向接口編程,知道了哪些接口可以調用了,具體實現需要框架提供一個代理類來為接口提供具體實現,讓消費者只管調用什么接口,而具體實現的獲取由代理類來處理。
消費者還需要提供調用方法名以及方法的參數值。
但是代理類此時還不知道需要調用哪個服務器上的遠程方法,此時需要一個注冊中心,通過注冊中心獲取可以調用的遠程服務列表。
遠程服務器一般都是集群部署,那么調用哪個服務器則需要通過負載均衡來選擇一個最合適的服務器來調用。
同時還需要有集群容錯機制,因為各種原因,可能遠程調用會失敗,此時需要容錯機制來重試調用,保證遠程調用的穩定性。
同時與服務提供方約定好通信協議和序列化格式,方便通信以及數據傳輸。
即暴露服務的服務提供方,服務提供方內部實現具體的接口,然后將接口暴露出去,再將服務注冊到注冊中心,服務消費方調用服務,提供者接收到調用請求后,通過約定好的通信協議來處理該請求,然后做反序列化,完成后,將請求放入線程池中處理,某個線程接收到這個請求然后找到對應的接口實現進行調用,然后將調用結果原路返回。
即服務注冊與發現的注冊中心,注冊中心負責服務地址的注冊與查找,相當于服務目錄,服務提供者和消費者只會再啟動時與注冊中心交互,注冊中心不轉發請求,壓力小。
注冊中心還可以集中化處理配置以及動態地將變更通知訂閱方。
但是為什么需要注冊中心呢?沒有注冊中心不可以嗎?
在沒有注冊中心,各服務之間的調用關系是這樣的:
當服務越來越多時,服務URL配置管理變得非常困難,硬件負載均衡器的單點壓力也越來越大,而有了注冊中心之后,就可以實現服務的統一管理,并且實現軟負載均衡,降低硬件成本,以下為注冊中心示意圖:
即統計服務調用次數和調用時間的監控中心,面對眾多服務,精細化的監控和方便的運維是不可或缺的,對后期維護相當重要。
即服務運行的容器。
圖中的各個節點充當的角色已經介紹過了,以下是各節點之間調用關系:
Container
服務容器負責啟動,加載以及運行
Provider
服務提供者Provider
服務提供者啟動時,需要將自身暴露出去讓遠程服務器可以發現,同時向Registry
注冊中心注冊自己提供的服務
Consumer
服務消費者啟動時,向Registry
注冊中心訂閱所需要的服務
Registry
注冊中心返回服務提供者列表給消費者,同時如果發生變更,注冊中心將基于長連接推送實時數據給消費者
服務消費者需要調用遠程服務時,會從提供者的地址列表中,基于負載均衡算法選出一臺提供者服務器進行調用,如果調用失敗,會基于集群容錯策略進行調用重試
服務消費者與提供者會在內存中統計調用次數和調用時間,然后通過定時任務將數據發送給Monitor
監控中心
監控中心宕機后不會對服務造成影響,只是丟失部分統計數據
注冊中心集群后,任意一臺宕機后,將自動切換到其他注冊中心
當所有注冊中心均宕機后,服務提供者和消費者之間仍然能通過本地記錄了彼此信息的緩存進行通訊,但是如果一方產生變更,另外一方無法感知
服務提供者無狀態,任意一臺服務器宕機后不影響使用,會有其他服務提供者提供服務
當所有服務提供者宕機后,服務消費者無法正常使用,將進行無限次重連等待服務提供者重新連線恢復
大的分層為Business(業務邏輯層)、RPC層和Remoting層。
再細分下來,Dubbo一共有十層架構,作用分別如下:
Service
,業務層,即日常開發中的業務邏輯層
Config
,配置層,對外配置接口,以ServiceConfig
和ReferenceConfig
為中心,可以直接初始化配置類,也可以通過Spring解析配置生成配置類
Proxy
,服務代理層,服務接口透明代理,生成服務的客戶端Stub
和客戶端Skeleton
,負責遠程調用和返回結果
Registry
,注冊中心層,封裝服務地址的注冊與發現,以服務URL為中心,拓展接口為RegistryFactory
,Registry
,RegistryService
Cluster
路由和集群容錯層,封裝了多個提供者的路由、負載均衡以及集群容錯,并橋接注冊中心,負責通過負載均衡選取調用具體的節點,處理特殊調用請求和負責遠程調用失敗的容錯措施
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,最終調用對應的實現類然后將結果原路返回。
感謝各位的閱讀!關于“java開發分布式服務框架Dubbo原理機制的示例分析”這篇文章就分享到這里了,希望以上內容可以對大家有一定的幫助,讓大家可以學到更多知識,如果覺得文章不錯,可以把它分享出去讓更多的人看到吧!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。