Dubbo理论知识
本文是作者根據(jù)官方文檔以及自己平時(shí)的使用情況,對(duì) Dubbo 所做的一個(gè)總結(jié)。如果不懂 Dubbo 的使用的話,可以參考我的這篇文章《超詳細(xì),新手都能看懂 !使用SpringBoot+Dubbo 搭建一個(gè)簡單的分布式服務(wù)》
Dubbo 官網(wǎng):http://dubbo.apache.org/zh-cn/index.html
Dubbo 中文文檔:?http://dubbo.apache.org/zh-cn/index.html
- 一 重要的概念
- 1.1 什么是 Dubbo?
- 1.2 什么是 RPC?RPC原理是什么?
- 1.3 為什么要用 Dubbo?
- 1.4 什么是分布式?
- 1.5 為什么要分布式?
- 二 Dubbo 的架構(gòu)
- 2.1 Dubbo 的架構(gòu)圖解
- 2.2 Dubbo 工作原理
- 三 Dubbo 的負(fù)載均衡策略
- 3.1 先來解釋一下什么是負(fù)載均衡
- 3.2 再來看看 Dubbo 提供的負(fù)載均衡策略
- 3.2.1 Random LoadBalance(默認(rèn),基于權(quán)重的隨機(jī)負(fù)載均衡機(jī)制)
- 3.2.2 RoundRobin LoadBalance(不推薦,基于權(quán)重的輪詢負(fù)載均衡機(jī)制)
- 3.2.3 LeastActive LoadBalance
- 3.2.4 ConsistentHash LoadBalance
- 3.3 配置方式
- 四 zookeeper宕機(jī)與dubbo直連的情況
一 重要的概念
1.1 什么是 Dubbo?
Apache Dubbo (incubating) |?d?b??| 是一款高性能、輕量級(jí)的開源Java RPC 框架,它提供了三大核心能力:面向接口的遠(yuǎn)程方法調(diào)用,智能容錯(cuò)和負(fù)載均衡,以及服務(wù)自動(dòng)注冊(cè)和發(fā)現(xiàn)。簡單來說 Dubbo 是一個(gè)分布式服務(wù)框架,致力于提供高性能和透明化的RPC遠(yuǎn)程服務(wù)調(diào)用方案,以及SOA服務(wù)治理方案。
Dubbo 目前已經(jīng)有接近 23k 的 Star ,Dubbo的Github 地址:https://github.com/apache/incubator-dubbo?。 另外,在開源中國舉行的2018年度最受歡迎中國開源軟件這個(gè)活動(dòng)的評(píng)選中,Dubbo 更是憑借其超高人氣僅次于 vue.js 和 ECharts 獲得第三名的好成績。
Dubbo 是由阿里開源,后來加入了 Apache 。正式由于 Dubbo 的出現(xiàn),才使得越來越多的公司開始使用以及接受分布式架構(gòu)。
我們上面說了 Dubbo 實(shí)際上是 RPC 框架,那么什么是 RPC呢?
1.2 什么是 RPC?RPC原理是什么?
什么是 RPC?
RPC(Remote Procedure Call)—遠(yuǎn)程過程調(diào)用,它是一種通過網(wǎng)絡(luò)從遠(yuǎn)程計(jì)算機(jī)程序上請(qǐng)求服務(wù),而不需要了解底層網(wǎng)絡(luò)技術(shù)的協(xié)議。比如兩個(gè)不同的服務(wù) A、B 部署在兩臺(tái)不同的機(jī)器上,那么服務(wù) A 如果想要調(diào)用服務(wù) B 中的某個(gè)方法該怎么辦呢?使用 HTTP請(qǐng)求 當(dāng)然可以,但是可能會(huì)比較慢而且一些優(yōu)化做的并不好。 RPC 的出現(xiàn)就是為了解決這個(gè)問題。
RPC原理是什么?
我這里這是簡單的提一下。詳細(xì)內(nèi)容可以查看下面這篇文章:
http://www.importnew.com/22003.html
下面再貼一個(gè)網(wǎng)上的時(shí)序圖:
說了這么多,我們?yōu)槭裁匆?Dubbo 呢?
1.3 為什么要用 Dubbo?
Dubbo 的誕生和 SOA 分布式架構(gòu)的流行有著莫大的關(guān)系。SOA 面向服務(wù)的架構(gòu)(Service Oriented Architecture),也就是把工程按照業(yè)務(wù)邏輯拆分成服務(wù)層、表現(xiàn)層兩個(gè)工程。服務(wù)層中包含業(yè)務(wù)邏輯,只需要對(duì)外提供服務(wù)即可。表現(xiàn)層只需要處理和頁面的交互,業(yè)務(wù)邏輯都是調(diào)用服務(wù)層的服務(wù)來實(shí)現(xiàn)。SOA架構(gòu)中有兩個(gè)主要角色:服務(wù)提供者(Provider)和服務(wù)使用者(Consumer)。
如果你要開發(fā)分布式程序,你也可以直接基于 HTTP 接口進(jìn)行通信,但是為什么要用 Dubbo呢?
我覺得主要可以從 Dubbo 提供的下面四點(diǎn)特性來說為什么要用 Dubbo:
另外,Dubbo 除了能夠應(yīng)用在分布式系統(tǒng)中,也可以應(yīng)用在現(xiàn)在比較火的微服務(wù)系統(tǒng)中。不過,由于 Spring Cloud 在微服務(wù)中應(yīng)用更加廣泛,所以,我覺得一般我們提 Dubbo 的話,大部分是分布式系統(tǒng)的情況。
我們剛剛提到了分布式這個(gè)概念,下面再給大家介紹一下什么是分布式?為什么要分布式?
1.4 什么是分布式?
分布式或者說 SOA 分布式重要的就是面向服務(wù),說簡單的分布式就是我們把整個(gè)系統(tǒng)拆分成不同的服務(wù)然后將這些服務(wù)放在不同的服務(wù)器上減輕單體服務(wù)的壓力提高并發(fā)量和性能。比如電商系統(tǒng)可以簡單地拆分成訂單系統(tǒng)、商品系統(tǒng)、登錄系統(tǒng)等等,拆分之后的每個(gè)服務(wù)可以部署在不同的機(jī)器上,如果某一個(gè)服務(wù)的訪問量比較大的話也可以將這個(gè)服務(wù)同時(shí)部署在多臺(tái)機(jī)器上。
1.5 為什么要分布式?
從開發(fā)角度來講單體應(yīng)用的代碼都集中在一起,而分布式系統(tǒng)的代碼根據(jù)業(yè)務(wù)被拆分。所以,每個(gè)團(tuán)隊(duì)可以負(fù)責(zé)一個(gè)服務(wù)的開發(fā),這樣提升了開發(fā)效率。另外,代碼根據(jù)業(yè)務(wù)拆分之后更加便于維護(hù)和擴(kuò)展。
另外,我覺得將系統(tǒng)拆分成分布式之后不光便于系統(tǒng)擴(kuò)展和維護(hù),更能提高整個(gè)系統(tǒng)的性能。你想一想嘛?把整個(gè)系統(tǒng)拆分成不同的服務(wù)/系統(tǒng),然后每個(gè)服務(wù)/系統(tǒng) 單獨(dú)部署在一臺(tái)服務(wù)器上,是不是很大程度上提高了系統(tǒng)性能呢?
二 Dubbo 的架構(gòu)
2.1 Dubbo 的架構(gòu)圖解
上述節(jié)點(diǎn)簡單說明:
- Provider:?暴露服務(wù)的服務(wù)提供方
- Consumer:?調(diào)用遠(yuǎn)程服務(wù)的服務(wù)消費(fèi)方
- Registry:?服務(wù)注冊(cè)與發(fā)現(xiàn)的注冊(cè)中心
- Monitor:?統(tǒng)計(jì)服務(wù)的調(diào)用次數(shù)和調(diào)用時(shí)間的監(jiān)控中心
- Container:?服務(wù)運(yùn)行容器
調(diào)用關(guān)系說明:
重要知識(shí)點(diǎn)總結(jié):
- 注冊(cè)中心負(fù)責(zé)服務(wù)地址的注冊(cè)與查找,相當(dāng)于目錄服務(wù),服務(wù)提供者和消費(fèi)者只在啟動(dòng)時(shí)與注冊(cè)中心交互,注冊(cè)中心不轉(zhuǎn)發(fā)請(qǐng)求,壓力較小
- 監(jiān)控中心負(fù)責(zé)統(tǒng)計(jì)各服務(wù)調(diào)用次數(shù),調(diào)用時(shí)間等,統(tǒng)計(jì)先在內(nèi)存匯總后每分鐘一次發(fā)送到監(jiān)控中心服務(wù)器,并以報(bào)表展示
- 注冊(cè)中心,服務(wù)提供者,服務(wù)消費(fèi)者三者之間均為長連接,監(jiān)控中心除外
- 注冊(cè)中心通過長連接感知服務(wù)提供者的存在,服務(wù)提供者宕機(jī),注冊(cè)中心將立即推送事件通知消費(fèi)者
- 注冊(cè)中心和監(jiān)控中心全部宕機(jī),不影響已運(yùn)行的提供者和消費(fèi)者,消費(fèi)者在本地緩存了提供者列表
- 注冊(cè)中心和監(jiān)控中心都是可選的,服務(wù)消費(fèi)者可以直連服務(wù)提供者
- 服務(wù)提供者無狀態(tài),任意一臺(tái)宕掉后,不影響使用
- 服務(wù)提供者全部宕掉后,服務(wù)消費(fèi)者應(yīng)用將無法使用,并無限次重連等待服務(wù)提供者恢復(fù)
2.2 Dubbo 工作原理
圖中從下至上分為十層,各層均為單向依賴,右邊的黑色箭頭代表層之間的依賴關(guān)系,每一層都可以剝離上層被復(fù)用,其中,Service 和 Config 層為 API,其它各層均為 SPI。
各層說明:
- 第一層:service層,接口層,給服務(wù)提供者和消費(fèi)者來實(shí)現(xiàn)的
- 第二層:config層,配置層,主要是對(duì)dubbo進(jìn)行各種配置的
- 第三層:proxy層,服務(wù)接口透明代理,生成服務(wù)的客戶端 Stub 和服務(wù)器端 Skeleton
- 第四層:registry層,服務(wù)注冊(cè)層,負(fù)責(zé)服務(wù)的注冊(cè)與發(fā)現(xiàn)
- 第五層:cluster層,集群層,封裝多個(gè)服務(wù)提供者的路由以及負(fù)載均衡,將多個(gè)實(shí)例組合成一個(gè)服務(wù)
- 第六層:monitor層,監(jiān)控層,對(duì)rpc接口的調(diào)用次數(shù)和調(diào)用時(shí)間進(jìn)行監(jiān)控
- 第七層:protocol層,遠(yuǎn)程調(diào)用層,封裝rpc調(diào)用
- 第八層:exchange層,信息交換層,封裝請(qǐng)求響應(yīng)模式,同步轉(zhuǎn)異步
- 第九層:transport層,網(wǎng)絡(luò)傳輸層,抽象mina和netty為統(tǒng)一接口
- 第十層:serialize層,數(shù)據(jù)序列化層,網(wǎng)絡(luò)傳輸需要
三 Dubbo 的負(fù)載均衡策略
3.1 先來解釋一下什么是負(fù)載均衡
先來個(gè)官方的解釋。
維基百科對(duì)負(fù)載均衡的定義:負(fù)載均衡改善了跨多個(gè)計(jì)算資源(例如計(jì)算機(jī),計(jì)算機(jī)集群,網(wǎng)絡(luò)鏈接,中央處理單元或磁盤驅(qū)動(dòng)的的工作負(fù)載分布。負(fù)載平衡旨在優(yōu)化資源使用,最大化吞吐量,最小化響應(yīng)時(shí)間,并避免任何單個(gè)資源的過載。使用具有負(fù)載平衡而不是單個(gè)組件的多個(gè)組件可以通過冗余提高可靠性和可用性。負(fù)載平衡通常涉及專用軟件或硬件。
上面講的大家可能不太好理解,再用通俗的話給大家說一下。
比如我們的系統(tǒng)中的某個(gè)服務(wù)的訪問量特別大,我們將這個(gè)服務(wù)部署在了多臺(tái)服務(wù)器上,當(dāng)客戶端發(fā)起請(qǐng)求的時(shí)候,多臺(tái)服務(wù)器都可以處理這個(gè)請(qǐng)求。那么,如何正確選擇處理該請(qǐng)求的服務(wù)器就很關(guān)鍵。假如,你就要一臺(tái)服務(wù)器來處理該服務(wù)的請(qǐng)求,那該服務(wù)部署在多臺(tái)服務(wù)器的意義就不復(fù)存在了。負(fù)載均衡就是為了避免單個(gè)服務(wù)器響應(yīng)同一請(qǐng)求,容易造成服務(wù)器宕機(jī)、崩潰等問題,我們從負(fù)載均衡的這四個(gè)字就能明顯感受到它的意義。
3.2 再來看看 Dubbo 提供的負(fù)載均衡策略
在集群負(fù)載均衡時(shí),Dubbo 提供了多種均衡策略,默認(rèn)為?random?隨機(jī)調(diào)用。可以自行擴(kuò)展負(fù)載均衡策略,參見:負(fù)載均衡擴(kuò)展。
備注:下面的圖片來自于:尚硅谷2018Dubbo 視頻。
3.2.1 Random LoadBalance(默認(rèn),基于權(quán)重的隨機(jī)負(fù)載均衡機(jī)制)
- 隨機(jī),按權(quán)重設(shè)置隨機(jī)概率。
- 在一個(gè)截面上碰撞的概率高,但調(diào)用量越大分布越均勻,而且按概率使用權(quán)重后也比較均勻,有利于動(dòng)態(tài)調(diào)整提供者權(quán)重。
3.2.2 RoundRobin LoadBalance(不推薦,基于權(quán)重的輪詢負(fù)載均衡機(jī)制)
- 輪循,按公約后的權(quán)重設(shè)置輪循比率。
- 存在慢的提供者累積請(qǐng)求的問題,比如:第二臺(tái)機(jī)器很慢,但沒掛,當(dāng)請(qǐng)求調(diào)到第二臺(tái)時(shí)就卡在那,久而久之,所有請(qǐng)求都卡在調(diào)到第二臺(tái)上。
3.2.3 LeastActive LoadBalance
- 最少活躍調(diào)用數(shù),相同活躍數(shù)的隨機(jī),活躍數(shù)指調(diào)用前后計(jì)數(shù)差。
- 使慢的提供者收到更少請(qǐng)求,因?yàn)樵铰奶峁┱叩恼{(diào)用前后計(jì)數(shù)差會(huì)越大。
3.2.4 ConsistentHash LoadBalance
- 一致性 Hash,相同參數(shù)的請(qǐng)求總是發(fā)到同一提供者。(如果你需要的不是隨機(jī)負(fù)載均衡,是要一類請(qǐng)求都到一個(gè)節(jié)點(diǎn),那就走這個(gè)一致性hash策略。)
- 當(dāng)某一臺(tái)提供者掛時(shí),原本發(fā)往該提供者的請(qǐng)求,基于虛擬節(jié)點(diǎn),平攤到其它提供者,不會(huì)引起劇烈變動(dòng)。
- 算法參見:http://en.wikipedia.org/wiki/Consistent_hashing
- 缺省只對(duì)第一個(gè)參數(shù) Hash,如果要修改,請(qǐng)配置?<dubbo:parameter key="hash.arguments" value="0,1" />
- 缺省用 160 份虛擬節(jié)點(diǎn),如果要修改,請(qǐng)配置?<dubbo:parameter key="hash.nodes" value="320" />
3.3 配置方式
xml 配置方式
服務(wù)端服務(wù)級(jí)別
<dubbo:service interface="..." loadbalance="roundrobin" />客戶端服務(wù)級(jí)別
<dubbo:reference interface="..." loadbalance="roundrobin" />服務(wù)端方法級(jí)別
<dubbo:service interface="..."> <dubbo:method name="..." loadbalance="roundrobin"/> </dubbo:service>客戶端方法級(jí)別
<dubbo:reference interface="..."> <dubbo:method name="..." loadbalance="roundrobin"/> </dubbo:reference>注解配置方式:
消費(fèi)方基于基于注解的服務(wù)級(jí)別配置方式:
@Reference(loadbalance = "roundrobin") HelloService helloService;四 zookeeper宕機(jī)與dubbo直連的情況
zookeeper宕機(jī)與dubbo直連的情況在面試中可能會(huì)被經(jīng)常問到,所以要引起重視。
在實(shí)際生產(chǎn)中,假如zookeeper注冊(cè)中心宕掉,一段時(shí)間內(nèi)服務(wù)消費(fèi)方還是能夠調(diào)用提供方的服務(wù)的,實(shí)際上它使用的本地緩存進(jìn)行通訊,這只是dubbo健壯性的一種提現(xiàn)。
dubbo的健壯性表現(xiàn):
我們前面提到過:注冊(cè)中心負(fù)責(zé)服務(wù)地址的注冊(cè)與查找,相當(dāng)于目錄服務(wù),服務(wù)提供者和消費(fèi)者只在啟動(dòng)時(shí)與注冊(cè)中心交互,注冊(cè)中心不轉(zhuǎn)發(fā)請(qǐng)求,壓力較小。所以,我們可以完全可以繞過注冊(cè)中心——采用?dubbo 直連?,即在服務(wù)消費(fèi)方配置服務(wù)提供方的位置信息。
xml配置方式:
<dubbo:reference id="userService" interface="com.zang.gmall.service.UserService" url="dubbo://localhost:20880" />注解方式:
@Reference(url = "127.0.0.1:20880") HelloService helloService;轉(zhuǎn)載于:https://www.cnblogs.com/iwenwen/p/11052085.html
總結(jié)
- 上一篇: 【文章】一副对联,便写尽了人生
- 下一篇: SpringBoot整合升级Spring