1 dubbox簡介
隨著互聯(lián)網(wǎng)的發(fā)展,網(wǎng)站應(yīng)用的規(guī)模不斷擴(kuò)大,常規(guī)的垂直應(yīng)用架構(gòu)已無法應(yīng)對,分布式服務(wù)架構(gòu)以及流動(dòng)計(jì)算架構(gòu)勢在必行,亟需一個(gè)治理系統(tǒng)確保架構(gòu)有條不紊的演進(jìn)。

** 單一應(yīng)用架構(gòu) **
當(dāng)網(wǎng)站流量很小時(shí),只需一個(gè)應(yīng)用,將所有功能都部署在一起,以減少部署節(jié)點(diǎn)和成本。
此時(shí),用于簡化增刪改查工作量的 數(shù)據(jù)訪問框架(ORM) 是關(guān)鍵。
垂直應(yīng)用架構(gòu)
當(dāng)訪問量逐漸增大,單一應(yīng)用增加機(jī)器帶來的加速度越來越小,將應(yīng)用拆成互不相干的幾個(gè)應(yīng)用,以提升效率。
此時(shí),用于加速前端頁面開發(fā)的 Web框架(MVC) 是關(guān)鍵。
分布式服務(wù)架構(gòu)
當(dāng)垂直應(yīng)用越來越多,應(yīng)用之間交互不可避免,將核心業(yè)務(wù)抽取出來,作為獨(dú)立的服務(wù),逐漸形成穩(wěn)定的服務(wù)中心,使前端應(yīng)用能更快速的響應(yīng)多變的市場需求。
此時(shí),用于提高業(yè)務(wù)復(fù)用及整合的 分布式服務(wù)框架(RPC) 是關(guān)鍵。
**流動(dòng)計(jì)算架構(gòu) **
當(dāng)服務(wù)越來越多,容量的評估,小服務(wù)資源的浪費(fèi)等問題逐漸顯現(xiàn),此時(shí)需增加一個(gè)調(diào)度中心基于訪問壓力實(shí)時(shí)管理集群容量,提高集群利用率。
此時(shí),用于提高機(jī)器利用率的 資源調(diào)度和治理中心(SOA) 是關(guān)鍵。
dubbox是dubbo的擴(kuò)展,主要在dubbo的基礎(chǔ)上進(jìn)行了一下的改進(jìn):
1、支持REST風(fēng)格遠(yuǎn)程調(diào)用(HTTP + JSON/XML):基于非常成熟的JBoss RestEasy框架,在dubbo中實(shí)現(xiàn)了REST風(fēng)格(HTTP + JSON/XML)的遠(yuǎn)程調(diào)用,以顯著簡化企業(yè)內(nèi)部的跨語言交互,同時(shí)顯著簡化企業(yè)對外的Open API、無線API甚至AJAX服務(wù)端等等的開發(fā)。事實(shí)上,這個(gè)REST調(diào)用也使得Dubbo可以對當(dāng)今特別流行的“微服務(wù)”架構(gòu)提供基礎(chǔ)性支持。 另外,REST調(diào)用也達(dá)到了比較高的性能,在基準(zhǔn)測試下,HTTP + JSON與Dubbo 2.x默認(rèn)的RPC協(xié)議(即TCP + Hessian2二進(jìn)制序列化)之間只有1.5倍左右的差距,詳見文檔中的基準(zhǔn)測試報(bào)告。
2、支持基于Kryo和FST的Java高效序列化實(shí)現(xiàn):基于當(dāng)今比較知名的Kryo和FST高性能序列化庫,為Dubbo默認(rèn)的RPC協(xié)議添加新的序列化實(shí)現(xiàn),并優(yōu)化調(diào)整了其序列化體系,比較顯著的提高了Dubbo RPC的性能,詳見文檔中的基準(zhǔn)測試報(bào)告。
3、支持基于Jackson的JSON序列化:基于業(yè)界應(yīng)用最廣泛的Jackson序列化庫,為Dubbo默認(rèn)的RPC協(xié)議添加新的JSON序列化實(shí)現(xiàn)。
4、支持基于嵌入式Tomcat的HTTP remoting體系:基于嵌入式tomcat實(shí)現(xiàn)dubbo的HTTP remoting體系(即dubbo-remoting-http),用以逐步取代Dubbo中舊版本的嵌入式Jetty,可以顯著的提高REST等的遠(yuǎn)程調(diào)用性能,并將Servlet API的支持從2.5升級到3.1。(注:除了REST,dubbo中的WebServices、Hessian、HTTP Invoker等協(xié)議都基于這個(gè)HTTP remoting體系)。
5、升級spring:將dubbo中Spring由2.x升級到目前最常用的3.x版本,減少版本沖突帶來的麻煩。
6、升級ZooKeeper客戶端:將dubbo中的zookeeper客戶端升級到最新的版本,以修正老版本中包含的bug。
7、支持完全基于Java代碼的Dubbo配置:基于Spring的Java Config,實(shí)現(xiàn)完全無XML的純Java代碼方式來配置dubbo
8、調(diào)整Demo應(yīng)用:暫時(shí)將dubbo的demo應(yīng)用調(diào)整并改寫以主要演示REST功能、Dubbo協(xié)議的新序列化方式、基于Java代碼的Spring配置等等。
9、修正了dubbo的bug 包括配置、序列化、管理界面等等的bug。
2 dubbo架構(gòu)構(gòu)成
dubbo運(yùn)行架構(gòu)如下圖示:

- 節(jié)點(diǎn)角色說明:
1、Provider:暴露服務(wù)的服務(wù)提供方。
Consumer: 調(diào)用遠(yuǎn)程服務(wù)的服務(wù)消費(fèi)方。
2、Registry:服務(wù)注冊與發(fā)現(xiàn)的注冊中心。
Monitor: 統(tǒng)計(jì)服務(wù)的調(diào)用次調(diào)和調(diào)用時(shí)間的監(jiān)控中心。
3、Container: 服務(wù)運(yùn)行容器。
- 調(diào)用關(guān)系說明:
1、服務(wù)容器負(fù)責(zé)啟動(dòng),加載,運(yùn)行服務(wù)提供者。
2、服務(wù)提供者在啟動(dòng)時(shí),向注冊中心注冊自己提供的服務(wù)。
3、服務(wù)消費(fèi)者在啟動(dòng)時(shí),向注冊中心訂閱自己所需的服務(wù)。
4、注冊中心返回服務(wù)提供者地址列表給消費(fèi)者,如果有變更,注冊中心將基于長連接推送變更數(shù)據(jù)給消費(fèi)者。
5、服務(wù)消費(fèi)者,從提供者地址列表中,基于軟負(fù)載均衡算法,選一臺(tái)提供者進(jìn)行調(diào)用,如果調(diào)用失敗,再選另一臺(tái)調(diào)用。
6、服務(wù)消費(fèi)者和提供者,在內(nèi)存中累計(jì)調(diào)用次數(shù)和調(diào)用時(shí)間,定時(shí)每分鐘發(fā)送一次統(tǒng)計(jì)數(shù)據(jù)到監(jiān)控中心。
3 dubbo的特性
(1) 連通性:
注冊中心負(fù)責(zé)服務(wù)地址的注冊與查找,相當(dāng)于目錄服務(wù),服務(wù)提供者和消費(fèi)者只在啟動(dòng)時(shí)與注冊中心交互,注冊中心不轉(zhuǎn)發(fā)請求,壓力較小監(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)表展示服務(wù)提供者向注冊中心注冊其提供的服務(wù),并匯報(bào)調(diào)用時(shí)間到監(jiān)控中心,此時(shí)間不包含網(wǎng)絡(luò)開銷服務(wù)消費(fèi)者向注冊中心獲取服務(wù)提供者地址列表,并根據(jù)負(fù)載算法直接調(diào)用提供者,同時(shí)匯報(bào)調(diào)用時(shí)間到監(jiān)控中心,此時(shí)間包含網(wǎng)絡(luò)開銷注冊中心,服務(wù)提供者,服務(wù)消費(fèi)者三者之間均為長連接,監(jiān)控中心除外注冊中心通過長連接感知服務(wù)提供者的存在,服務(wù)提供者宕機(jī),注冊中心將立即推送事件通知消費(fèi)者注冊中心和監(jiān)控中心全部宕機(jī),不影響已運(yùn)行的提供者和消費(fèi)者,消費(fèi)者在本地緩存了提供者列表
注冊中心和監(jiān)控中心都是可選的,服務(wù)消費(fèi)者可以直連服務(wù)提供者
(2) 健狀性:
監(jiān)控中心宕掉不影響使用,只是丟失部分采樣數(shù)據(jù)數(shù)據(jù)庫宕掉后,注冊中心仍能通過緩存提供服務(wù)列表查詢,但不能注冊新服務(wù)注冊中心對等集群,任意一臺(tái)宕掉后,將自動(dòng)切換到另一臺(tái)注冊中心全部宕掉后,服務(wù)提供者和服務(wù)消費(fèi)者仍能通過本地緩存通訊服務(wù)提供者無狀態(tài),任意一臺(tái)宕掉后,不影響使用服務(wù)提供者全部宕掉后,服務(wù)消費(fèi)者應(yīng)用將無法使用,并無限次重連等待服務(wù)提供者恢復(fù)
(3) 伸縮性:
注冊中心為對等集群,可動(dòng)態(tài)增加機(jī)器部署實(shí)例,所有客戶端將自動(dòng)發(fā)現(xiàn)新的注冊中心
服務(wù)提供者無狀態(tài),可動(dòng)態(tài)增加機(jī)器部署實(shí)例,注冊中心將推送新的服務(wù)提供者信息給消費(fèi)者
(4) 升級性:
當(dāng)服務(wù)集群規(guī)模進(jìn)一步擴(kuò)大,帶動(dòng)IT治理結(jié)構(gòu)進(jìn)一步升級,需要實(shí)現(xiàn)動(dòng)態(tài)部署,進(jìn)行流動(dòng)計(jì)算,現(xiàn)有分布式服務(wù)架構(gòu)不會(huì)帶來阻力:

4 dubbo的調(diào)用方式
- 異步調(diào)用
基于NIO的非阻塞實(shí)現(xiàn)并行調(diào)用,客戶端不需要啟動(dòng)多線程即可完成并行調(diào)用多個(gè)遠(yuǎn)程服務(wù),相對多線程開銷較小。

- 本地調(diào)用
本地調(diào)用,使用了Injvm協(xié)議,是一個(gè)偽協(xié)議,它不開啟端口,不發(fā)起遠(yuǎn)程調(diào)用,只在JVM內(nèi)直接關(guān)聯(lián),但執(zhí)行Dubbo的Filter鏈。

5 dubbo支持的注冊中心
Dubbo提供的注冊中心有如下幾種類型可供選擇:
- Multicast注冊中心
- Zookeeper注冊中心
- Redis注冊中心
- Simple注冊中心
ZooKeeper是一個(gè)開源的分布式服務(wù)框架,它是Apache Hadoop項(xiàng)目的一個(gè)子項(xiàng)目,主要用來解決分布式應(yīng)用場景中存在的一些問題,如:統(tǒng)一命名服務(wù)、狀態(tài)同步服務(wù)、集群管理、分布式應(yīng)用配置管理等,它支持Standalone模式和分布式模式,在分布式模式下,能夠?yàn)榉植际綉?yīng)用提供高性能和可靠地協(xié)調(diào)服務(wù),而且使用ZooKeeper可以大大簡化分布式協(xié)調(diào)服務(wù)的實(shí)現(xiàn),為開發(fā)分布式應(yīng)用極大地降低了成本。
ZooKeeper總體架構(gòu)

ZooKeeper集群由一組Server節(jié)點(diǎn)組成,這一組Server節(jié)點(diǎn)中存在一個(gè)角色為Leader的節(jié)點(diǎn),其他節(jié)點(diǎn)都為Follower。當(dāng)客戶端Client連接到ZooKeeper集群,并且執(zhí)行寫請求時(shí),這些請求會(huì)被發(fā)送到Leader節(jié)點(diǎn)上,然后Leader節(jié)點(diǎn)上數(shù)據(jù)變更會(huì)同步到集群中其他的Follower節(jié)點(diǎn)。
6 dubbo支持的遠(yuǎn)程通信協(xié)議
遠(yuǎn)程通信需要指定通信雙方所約定的協(xié)議,在保證通信雙方理解協(xié)議語義的基礎(chǔ)上,還要保證高效、穩(wěn)定的消息傳輸。Dubbo繼承了當(dāng)前主流的網(wǎng)絡(luò)通信框架,主要包括如下幾個(gè):
- Mina
- Netty
- Grizzly

7 dubbo支持的遠(yuǎn)程調(diào)用協(xié)議
Dubbo支持多種協(xié)議,如下所示:
- Dubbo協(xié)議
- Hessian協(xié)議
- HTTP協(xié)議
- RMI協(xié)議
- WebService協(xié)議
- Thrift協(xié)議
- Memcached協(xié)議
- Redis協(xié)議

在通信過程中,不同的服務(wù)等級一般對應(yīng)著不同的服務(wù)質(zhì)量,那么選擇合適的協(xié)議便是一件非常重要的事情。你可以根據(jù)你應(yīng)用的創(chuàng)建來選擇。例如,使用RMI協(xié)議,一般會(huì)受到防火墻的限制,所以對于外部與內(nèi)部進(jìn)行通信的場景,就不要使用RMI協(xié)議,而是基于HTTP協(xié)議或者Hessian協(xié)議。
8 dubbo集群容錯(cuò)和負(fù)載均衡
**1、集群容錯(cuò) **
在集群調(diào)用失敗時(shí),Dubbo提供了多種容錯(cuò)方案,缺省為failover重試。
**Failover Cluster **
失敗自動(dòng)切換,當(dāng)出現(xiàn)失敗,重試其它服務(wù)器。(缺省)
通常用于讀操作,但重試會(huì)帶來更長延遲。
可通過retries=“2”來設(shè)置重試次數(shù)(不含第一次)。**Failfast Cluster **
快速失敗,只發(fā)起一次調(diào)用,失敗立即報(bào)錯(cuò)。
通常用于非冪等性的寫操作,比如新增記錄。Failsafe Cluster
失敗安全,出現(xiàn)異常時(shí),直接忽略。
通常用于寫入審計(jì)日志等操作。Failback Cluster
失敗自動(dòng)恢復(fù),后臺(tái)記錄失敗請求,定時(shí)重發(fā)。
通常用于消息通知操作。Forking Cluster
并行調(diào)用多個(gè)服務(wù)器,只要一個(gè)成功即返回。
通常用于實(shí)時(shí)性要求較高的讀操作,但需要浪費(fèi)更多服務(wù)資源。
可通過forks=“2”來設(shè)置最大并行數(shù)。**Broadcast Cluster **
廣播調(diào)用所有提供者,逐個(gè)調(diào)用,任意一臺(tái)報(bào)錯(cuò)則報(bào)錯(cuò)。(2.1.0開始支持)
通常用于通知所有提供者更新緩存或日志等本地資源信息。
2、負(fù)載均衡
- Random LoadBalance隨機(jī),按權(quán)重設(shè)置隨機(jī)概率。
在一個(gè)截面上碰撞的概率高,但調(diào)用量越大分布越均勻,而且按概率使用權(quán)重后也比較均勻,有利于動(dòng)態(tài)調(diào)整提供者權(quán)重。
RoundRobin LoadBalance 輪循,按公約后的權(quán)重設(shè)置輪循比率。
存在慢的提供者累積請求問題,比如:第二臺(tái)機(jī)器很慢,但沒掛,當(dāng)請求調(diào)到第二臺(tái)時(shí)就卡在那,久而久之,所有請求都卡在調(diào)到第二臺(tái)上。LeastActive LoadBalance 最少活躍調(diào)用數(shù),相同活躍數(shù)的隨機(jī),活躍數(shù)指調(diào)用前后計(jì)數(shù)差。
使慢的提供者收到更少請求,因?yàn)樵铰奶峁┱叩恼{(diào)用前后計(jì)數(shù)差會(huì)越大。ConsistentHash LoadBalance 一致性Hash,相同參數(shù)的請求總是發(fā)到同一提供者。
當(dāng)某一臺(tái)提供者掛時(shí),原本發(fā)往該提供者的請求,基于虛擬節(jié)點(diǎn),平攤到其它提供者,不會(huì)引起劇烈變動(dòng)。
配置如:

9 dubbo源代碼結(jié)構(gòu)

Dubbo以包結(jié)構(gòu)來組織各個(gè)模塊,各個(gè)模塊及其關(guān)系,如圖所示:

dubbo-common 公共邏輯模塊,包括Util類和通用模型。
dubbo-remoting 遠(yuǎn)程通訊模塊,相當(dāng)于Dubbo協(xié)議的實(shí)現(xiàn),如果RPC用RMI協(xié)議則不需要使用此包。
dubbo-rpc 遠(yuǎn)程調(diào)用模塊,抽象各種協(xié)議,以及動(dòng)態(tài)代理,只包含一對一的調(diào)用,不關(guān)心集群的管理。
dubbo-cluster 集群模塊,將多個(gè)服務(wù)提供方偽裝為一個(gè)提供方,包括:負(fù)載均衡、容錯(cuò)、路由等,集群的地址列表可以是靜態(tài)配置的,也可以是由注冊中心下發(fā)。
dubbo-registry 注冊中心模塊,基于注冊中心下發(fā)地址的集群方式,以及對各種注冊中心的抽象。
dubbo-monitor 監(jiān)控模塊,統(tǒng)計(jì)服務(wù)調(diào)用次數(shù),調(diào)用時(shí)間的,調(diào)用鏈跟蹤的服務(wù)。
dubbo-config 配置模塊,是Dubbo對外的API,用戶通過Config使用Dubbo,隱藏Dubbo所有細(xì)節(jié)。
dubbo-Container 容器模塊,是一個(gè)Standalone的容器,以簡單的Main加載Spring啟動(dòng),因?yàn)榉?wù)通常不需要Tomcat/JBoss等Web容器的特性,沒必要用Web容器去加載服務(wù)。
10 Dubbo內(nèi)核實(shí)現(xiàn)之SPI簡單介紹
Dubbo采用微內(nèi)核+插件體系,使得設(shè)計(jì)優(yōu)雅,擴(kuò)展性強(qiáng)。那所謂的微內(nèi)核+插件體系是如何實(shí)現(xiàn)的呢!即我們定義了服務(wù)接口標(biāo)準(zhǔn),讓廠商去實(shí)現(xiàn)(如果不了解spi的請谷歌百度下), jdk通過ServiceLoader類實(shí)現(xiàn)spi機(jī)制的服務(wù)查找功能。
JDK實(shí)現(xiàn)spi服務(wù)查找: ServiceLoader
首先定義下示例接口

A廠商提供實(shí)現(xiàn)

com.a.example.SpiAImpl #廠商A的spi實(shí)現(xiàn)全路徑類名
B廠商提供實(shí)現(xiàn)

com.b.example.SpiBImpl #廠商B的spi實(shí)現(xiàn)全路徑類名
ServiceLoader.load(Spi.class)讀取廠商A、B提供jar包中的文件,ServiceLoader實(shí)現(xiàn)了Iterable接口可通過while for循環(huán)語句遍歷出所有實(shí)現(xiàn)。
一個(gè)接口多種實(shí)現(xiàn),就如策略模式一樣提供了策略的實(shí)現(xiàn),但是沒有提供策略的選擇, 使用方可以根據(jù)isSupport方法根據(jù)業(yè)務(wù)傳入廠商名來選擇具體的廠商。

定義了@SPI注解

具體實(shí)現(xiàn)的類有:

所以說:Remoting實(shí)現(xiàn)是Dubbo協(xié)議的實(shí)現(xiàn).
如何一起學(xué)習(xí),有沒有免費(fèi)資料?

本文由博客一文多發(fā)平臺(tái) OpenWrite 發(fā)布!