Dubbo基礎
什么是Dubbo?
Dubbo是Apache下的,一款高性能,輕量級,開源的java RPC框架。
根據Dubbo官方文檔的介紹,Dubbo提供了溜達核心能力:
- 面向接口代理的高性能RPC調用
- 智能容錯和負載均衡
- 服務自動擴展能力
- 高度可擴展能力
- 運行期流量調度
- 可視化的服務治理與運維
Dubbo核心能力
簡單來說,就是Dubbo不光可以幫助我們調用遠程服務,還提供了一些其它開箱即用的功能,比如說智能負載均衡。
為什么要用Dubbo?
隨著互聯網的發展,網絡的規模越來越大,用戶數量越來越多。單一應用的架構,垂直應用架構無法滿足我們的需求,這個時候分布式服務架構就誕生了。
分布式服務架構下,系統被拆分成不同的服務,比如短信服務,安全服務,每個服務都獨立提供系統的某個核心功能。
實際上Java中的RPC框架也有好幾個,比如Java RMI,Hession等。但是我們為什么選擇Dubbo呢?
因為Java RMI,Hession雖然也能實現遠程調用,但是更適合兩個服務之間相互調用。因為我工作以來就開始用dubbo,所以為了這篇筆記特意去搭了以上兩個框架的demo,下面附上一個我覺得寫的比較好的教程:Java常用的RPC框架-RMI,hessian,dubbo
大家去看下大概就能懂這兩個框架的原理,其實就是最基本框的RPC封裝。而且功能很少,只是單純的暴露和引用遠程服務。而且注冊中心還是很直觀的實現。相比于Dubbo的可視化注冊中心,負載均衡,服務監控等就迫在眉睫了。所以說Dubbo更受分布式系統的青睞(相比于RMI和Hession)。
Dubbo幫助我們解決了什么問題?
- 負載均衡:同一個服務部署在不同的機器時該調用一臺機器上的服務。
- 服務調用鏈路生成:隨著系統的發展,服務越來越多,服務之間依賴關系變得錯綜復雜,甚至分不清哪個應用要在哪個應用之前啟動,架構師都不能完整的描述應用的架構關系。Dubbo可以為我們解決服務之間互相是如何調用的。
-
服務訪問壓力以及時長統計,資源調度和治理:基于訪問壓力實時管理集群容量,提高集群利用率。
Dubbo服務治理
分布式基礎
什么是分布式?
分布式或者說SOA分布式重要的就是面向服務,說簡單的分布式就是我們把整個系統拆分成不同的服務放在不同的服務器上,減輕單體服務的壓力,提高并發量和性能。
比如電商系統可以簡單地拆分成訂單系統,商品系統,登錄系統等。拆分之后每個服務器可以部署在不同的機器上,如果某一個服務的訪問量比較大的話也可以將這個服務同時部署在多臺機器上。
為什么要分布式?
從開發角度來講,單體應用的代碼都集中在一起,而分布式系統的代碼根據業務被拆分。所以每個團隊可以負責一個服務的開發,這樣提升了開發效率。另外代碼根據業務拆分之后更加便于維護和擴展。
另外,將系統拆分成分布式之后不光便于系統擴展和維護,更能提高整個系統的性能。
Dubbo架構
Dubbo架構中的核心角色有哪些?
上述節點簡單介紹以及他們之間的關系:
- Container:服務運行容器,負責加載,運行服務提供者。
- Provider:暴露服務的服務提供方,會向注冊中心注冊自己提供的服務。
- Consumer:調用遠程服務的服務消費方,會向注冊中心訂閱自己所需的服務。
- Registry:服務注冊與發現的注冊中心。注冊中心會返回服務提供者地址列表給消費者。
- Monitor:統計服務的調用次數和調用時間的監控中心。服務消費者和提供者會定時發送統計數據到監控中心。
Dubbo中的Invoker概念是什么?
Invoker是Dubbo領域模型中非常重要的一個概念。簡單來說就是Dubbo對遠程調用的抽象:
按照Dubbo官方的話來說,Invoker分為:
- 服務提供Invoker
- 服務消費Invoker
假如我們需要調用一個遠程方法,我們需要動態代理來屏蔽遠程調用的細節。我們屏蔽掉的這些細節就依賴對應的Invoker實現,Invoker實現了真正的遠程服務調用。下面有一篇文章我覺得講的比較好,大家可以看看:深入理解Dubbo核心模型Invoker
Dubbo的工作原理
下圖是Dubbo的整體設計,從下到上分為十層,各層單項依賴。
- Service服務層:這個就比較簡單了,就是我們具體的代碼邏輯,其實也算不得是Dubbo的,不多說了。
- config配置層:Dubbo相關的配置,支持代碼配置,同時也支持基于Spring來做配置。以ServiceConfig,ReferenceConfig為中心。
- proxy服務代理層:調用遠程方法像調用本地方法一樣簡單的一個關鍵,真實調用過程依賴代理類,以ServiceProxy為中心。
- registry注冊中心層:封裝服務地址的注冊與發現。
- cluster路由層:封裝多個提供者的路由以及負載均衡,并橋接注冊中心,以Invoker為中心。
- monitor監控層:RPC調用次數和調用時間監控。以Statistics為中心。
- protocal遠程調用層:封裝RPC調用,以Invocation,Result為中心。
- exchange信息交換層:封裝請求響應模式,同步轉異步,以Request,Reponse為中心。
- transport網絡傳輸層:抽象mina和netty為統一接口,以Message為中心。
- serialize數據序列化層:對需要在網絡傳輸的數據進行序列化。
Dubbo的SPI機制是什么?如何讓擴展Dubbo中的默認實現?
SPI(Service Provider Interface)機制被大量用在開源項目中,它可以幫我們動態尋找服務/功能的實現。
SPI的具體原理是這樣的:我們將接口的實現類放在配置文件里,在程序運行過程中讀取配置文件,通過反射加載實現類。這樣我們可以在運行的時候,動態替換接口的實現類。和IOC的解耦思想是類似的。
java本身就提供了SPI機制的實現,不過dubbo沒有直接用,而是對java原生的spi機制進行了增強,以便更好的滿足自己的需求。
如何擴展Dubb中的默認實現呢?
比如說我們想要實現自己的負載均衡策略,可以創建對應的實現類xxLoadBalance實現LoadBalance接口或者AbstractLoadBalance類。
然后我們可以將這個實現類的路徑寫入到resources目錄下的META-INF/dubbo/org.apache.dubbo.rpc.cluster.LoadBalance文件中即可。
其實dubbo還支持很多可供擴展的選擇,我們可以去dubbo開發手冊中查看:https://cn.dubbo.apache.org/zh/docs3-v2/java-sdk/reference-manual/spi/description/
關于Dubbo的一些小問題
-
注冊中心的作用是什么?
注冊中心負責服務地址的注冊與查找,相當于目錄服務,服務提供者和消費者只在啟動時與注冊中心交互。 -
服務提供者宕機后,注冊中心會做什么?
注冊中心會立即推送事件通知消費者。 -
監控中心的作用呢?
監控中心負責統計各服務調用次數,調用時間等。 -
注冊中心和監控中心都宕機的話,服務都會掛掉么?
不會,兩者都宕機也不影響已運行的提供者和消費者。消費者在本地緩存了提供者列表。注冊中心和監控中心都是可選的,服務消費者可以直連服務提供者。
Dubbo的負載均衡策略
什么是負載均衡?
假如我們系統訪問量特別大,我們將這個服務部署在了多臺服務器上,當客戶端發生請求的時候,多臺服務器都可以處理這個請求。那么如何選擇處理該請求的服務器就很關鍵。負載均衡就是為了避免請求分配不合理而出現的。
Dubbo提供的負載均衡策略有哪些?
在集群負載均衡的時候,Dubbo提供了多種均衡策略。默認是random隨機調用。我們還可以自行擴展負載均衡策略。下面是dubbo提供的幾種策略。
RandomLoadBalance
根據權重隨機選擇,這是Dubbo默認采用的一種負載均衡策略。
這個實現原理非常簡單,比如說權重滿份100,S1權重12,S2權重22,S3權重76.那么就生成一個0-100的隨機數。前小于12就取S1,12到22之間就取S2,22到100之間就取S3。LeastActiveLoadBalance
這個直接說原理:每一個服務提供者對應一個活躍數。這個活躍數初始值為0.收到請求活躍數+1.處理完請求活躍數-1.因此,Dubbo會優先把請求給活躍數最小的服務提供者處理。如果多個提供者活躍數相同則再走一遍RandomLoadBalance。ConsistentHashLoadBalance
一致性hash負載均衡策略。ConsistentHashLoadBalance中沒有權重的概念。具體哪個服務提供者處理請求是由請求的參數決定的。也就是說相同的參數的請求總是發到同一個服務提供者上。RoundRobinLoadBalance
加權輪詢負載均衡。簡單可以理解成權重隨機的公平版。既然是基礎的權重比例。只不過這次不隨機獲取了,而是從前到后順序來。
Dubbo的序列化協議
Dubbo支持多種序列化方式,比如jdk自帶的序列化,hessian2,json,kryo,FST之類的。默認使用的是hessian2.
一般我們不會直接使用jdk自帶的序列化方式,主要原因有兩個:
- 不支持跨語言調用:如果調用的是其他語言開發的服務就不支持了。
- 性能差:相比于其它序列化框架性能更低,主要原因是序列化之后的字節數組體積較大,導致傳輸成本大。
JSON序列化由于性能問題,我們一般也不會考慮使用。
而Protostuff,ProtoBuf,hessian2這些都是跨語言的序列化方式,如果有跨語言需求的話可以考慮使用。
Kryo和FST是Dubbo后來才引入的,性能比較好,不過這兩個都專門針對java語言的。Dubbo官網的一篇文章提到過推薦使用Kryo作為生產環境的序列化方式。
本篇筆記就到這里,反正大部分都是八股文,如果對你有所幫助就點個喜歡點個關注吧,也希望大家工作順順利利,身體健健康康!