天天看點

dubbo詳細學習筆記

dubbo詳細學習筆記

第一章 基本概念

1. 什麼是dubbo

dubbo是一款高性能的RPC架構,可以和Spring架構無縫內建。dubbo提供了三大核心能力,面向接口的遠端方法調用,智能容錯和負載均衡以及服務自動注冊和發現

具體介紹參考dubbo官網:dubbo官網

2. 什麼是RPC

RPC即遠端過程調用,比如兩台伺服器A和B,A伺服器上部署一個應用,B伺服器部署一個應用,A伺服器上的應用調用B伺服器上的應用提供的方法,由于兩個應用不在一個記憶體空間,不能直接調用,是以需要通過網絡來表達調用的語義和傳達調用的資料。RPC架構比較多,像RMI,Hessian,gRPC ,dubbo等,核心子產品就是網絡通訊和序列化。

dubbo詳細學習筆記

RPC調用過程圖如下:

dubbo詳細學習筆記

3. RMI

(1)概念

RMI是java原生支援的遠端調用,采用JRMP作為通信協定,可以認為是java版本的分布式遠端調用方案。

(2)核心概念

dubbo詳細學習筆記

(3)RMI實作步驟

① 建立遠端接口,并且繼承java.rmi.Remote接口

② 實作遠端接口,并且繼承UnicastRemoteObject

③ 建立伺服器程式,createRegistry()方法注冊遠端對象

④ 建立用戶端程式,擷取注冊資訊,調用接口方法

具體實作如下:

dubbo詳細學習筆記
dubbo詳細學習筆記
dubbo詳細學習筆記
dubbo詳細學習筆記

4. Hessian

(1)Hessian使用C/S方式,基于HTTP協定傳輸,使用Hessian二進制序列化

(2)具體實作

server端,為war包,需要配置web.xml

① 導入依賴

dubbo詳細學習筆記

② 建立接口

dubbo詳細學習筆記

③ web.xnl

dubbo詳細學習筆記

用戶端

① 添加Hessian依賴

② 建立server端相同的接口,用戶端需要用到服務端的接口

③ 建立測試類進行測試

dubbo詳細學習筆記

第二章 dubbo高可用

1. 叢集容錯

(1)服務路由

服務路由包含一條路由規則,決定了服務消費者的調用目标,規定了服務消費者可調用哪些服務提供者

① [服務消費者比對條件]=>[服務提供者比對條件]

例如:host=10.20.152.10=>host=10.20.153.11

表示IP為10.20.152.10的服務消費者隻可調用IP為10.20.153.11機器上的服務

② 常用路由配置

白名單

host!=10.20.152.10,10.20.152.11=>

表示除了這兩個其他都可以調用

黑名單

host=10.20.152.10,10.20.152.11

這兩個ip不能進行消費,服務禁用

讀寫分離

method=find,list,get,is=>host=172.22.3.94,172.22.3.9,172.22.3.96

method!=find,list,get,is=>host=172.22.3.97,172.22.3.98

前背景分離

application=front=>host=172.22.3.92,172.22.3.93

application!=front=>host=172.22.3.92,172.22.3.93

(2)叢集容錯

① Failover Cluster失敗自動切換,當出現失敗,重試其他伺服器,通常用于讀操作,可通過retries=“2”設定重試次數

<dubbo :server retries=“2”/>或<dubbo :reference retries=“2”/>

② Failfast Cluster快速失敗,隻發起一次調用,失敗立即報錯,通常用于非幂等性的寫操作,比如新增記錄

③ Failsafe Cluster 失敗安全,出現異常時,直接忽略,通常用于寫入日志等操作

④ Failback Cluster失敗自動恢複,背景記錄失敗請求,定時重發,通常用于消息通知操作

⑤ Forking Cluster 并行調用多個伺服器,隻要一個成功即傳回,通常用于實時性要求較高的讀操作,可通過forks="2"來設定最大并行數

⑥ Broadcast Cluster廣播調用所有提供者,逐個調用,任意一台報錯則報錯,通知用于通知所有提供者更新緩存或日志等本地資源資訊

(3)負載均衡

① Random LoadBalance:按照權重設定随機機率,無狀态

② RoundRobin LoadBalance:輪詢,有狀态

③ LeastActive LoadBalance:最少活躍數随機,方法次元的統計服務調用數

④ ConsistentHash LoadBalance:一緻性Hash

2. 服務治理

(1)服務降級

服務提供方的編寫:

dubbo詳細學習筆記
dubbo詳細學習筆記

① dubbo配置-application.xml

dubbo詳細學習筆記

② 提供方接口實作暴露的接口

dubbo詳細學習筆記

③ web.xml 設定監聽

dubbo詳細學習筆記

服務消費者的編寫

① 配置檔案-application.xml

dubbo詳細學習筆記

② 編寫web.xml

dubbo詳細學習筆記

③ controller層代碼

dubbo詳細學習筆記

mock配置方式

mock的配置支援兩種,一種是boolean值,預設的為false,配置為true,則預設使用mock類名,即類名+Mock字尾;另外一種是配置“return null”,可以簡單的忽略掉異常

① mock配置在消費方,當消費方正常運作,擷取傳回值時為null

dubbo詳細學習筆記

② mock=“return null”會對service中的所有方法做統一處理。都傳回null值,如果我們要做其他處理則配置mock=“true”,同時實作mock接口,接口名+Mock字尾,如果調用失敗則會嗲用Mock實作,mock實作需要保證無參的構造方法

dubbo詳細學習筆記

在暴露的接口編寫Mock實作類

dubbo詳細學習筆記

3. 高可用整合Hystrix

(1) 添加依賴

dubbo詳細學習筆記

(2)在主程式啟動類上添加注解@EnableHystrix開啟Hystrix功能

dubbo詳細學習筆記

(3)在提供方增加@HystrixCommand注解,這樣調用會經過Hystrix代理

dubbo詳細學習筆記

(4)在消費方增加@HystrixCommand注解并指定出錯是的回調方法,當出錯時,會調用fallbackMethod裡的方法

dubbo詳細學習筆記

4. dubbo線程IO模型

(1)BIO:每個用戶端連接配接過來後,服務端會啟動一個線程去處理該用戶端的請求,阻塞I/O的通信

dubbo詳細學習筆記

在傳統的IO模型中,每個連接配接建立成功之後都需要一個線程來維護

(2)NIO:非阻塞IO,新來一個連接配接不在建立一個新的線程,而是把這條連接配接直接綁定到某個固定的線程,然後這條連接配接所有的讀寫都由這個線程負責

對比兩種IO

dubbo詳細學習筆記

說明:

① IO模型中,一個連接配接對應建立一個線程,對應一個死循環,死循環的目的就是不斷監測這條連接配接上是否有資料可讀,但是在大多數情況下,很多個while循環都白白浪費,沒有資料

② NIO模型中可以把這麼多的while死循環變成一個死循環,這個死循環由一個線程控制,這就是NIO模型中的選擇器的作用,一條連接配接來了,不是建立一個while死循環去監聽是否有資料可讀了,而是直接把這條連接配接注冊到選擇器上,通過檢查這個選擇器,就可以批量監測出有資料可讀的連接配接,進而讀取資料

5. dubbo原理

dubbo詳細學習筆記

說明:

① config配置層:對外配置接口,以ServiceConfig,ReferenceConfig為中心,可以直接初始化配置類也可以通過spring解析配置生成配置類

② proxy服務代理層:服務接口透明代理,生成服務的用戶端stub和伺服器端skeleton,以ServiceProxy為中心,擴充接口為ProxyFactory

③ registry注冊中心:封裝服務位址的注冊于發現,以服務URL為中心,擴充接口為RegistryFactory,Registry,RegistryService

6. dubbo SPI機制

(1)具體實作

① 建立一個接口和實作類

dubbo詳細學習筆記

② dubbo SPI所需的配置檔案放置在META-INF/dubbo路徑下,其檔案的包路徑要和service的包路徑一緻,檔案内容如下:根據key來進行通路的

dubbo詳細學習筆記

③ 進行測試

dubbo SPI的相關邏輯被封裝在ExtensionLoader類中,通過ExtensionLoader,我們可以加載指定的實作類,這裡需要注意的是需要在接口上标注@SPI注解,根據key來對應通路具體的實作類

dubbo詳細學習筆記

(2)源碼分析

① 通過getExtensionLoader方法擷取一個ExtensionLoader執行個體,該方法先從緩存中擷取與擴充類對應的ExtensionLoader,若緩存未命中,則建立一個新的執行個體

dubbo詳細學習筆記

② getExtension方法中,檢查緩存,未命中則調用createExtension方法建立擴充對象

dubbo詳細學習筆記

③ createExtension方法包含如下步驟:

通過getExtensionClasses擷取所有的擴充類

通過反射建立擴充對象

向擴充對象中注入依賴

将擴充對象包裹在相應的Wrapper對象中

dubbo詳細學習筆記

injectExtension方法依賴注入實作原理:dubbo首先會通過反射擷取到執行個體的所有方法,然後在周遊方法清單,檢測方法名是否具有setter方法特征,若有,則通過ObjectFactory擷取依賴對象,最後通過反射調用setter方法将依賴設定到目标對象中

dubbo詳細學習筆記

7. dubbo服務暴露源碼分析

(1)spring容器啟動,會加載BeanDefinitionParser類來解析配置檔案,dubbo配置檔案的加載依賴實作類DubboBeanDefinitionParser,DubboBeanDefinitionParser解析器會将配置檔案中不同的标簽解析成不同的xxxConfig,<dubbo:service/>,<dubbo:reference/>分别解析成serviceBean和referenceBean

dubbo詳細學習筆記

(2)serviceBean實作了InitializingBean和ApplicationListener接口,在afterPropertiesSet方法中主要将配置檔案中屬性依次配置到對應的bean中,在spring上下文重新整理事件後會回調onApplicationEvent方法

dubbo詳細學習筆記

(3)調用父類ServiceConfig對象的export方法,檢查延遲是否導出,執行doExportUrls

dubbo詳細學習筆記

(4)doExportURLs方法首先通過loadRegistries加載注冊中心連結,後在周遊ProtocolConfig集合導出每個服務,并在導出服務的過程中,将服務注冊到注冊中心

dubbo詳細學習筆記

(5)doExportUrlsForProtocol方法主要将版本,時間戳,方法名以及各種配置對象的字段資訊放入到map中,map中的内容将作為URL的查詢字元串,建構好map後,緊接着是擷取上下文路徑,主機名和端口号資訊,最後将map和主機名等資料傳給URL構造方法建立RUL對象

dubbo詳細學習筆記

(6)導出服務

scope=none則不做處理,scope!=remote導出本地服務,scope!=local則導出遠端服務,不管哪一種導出服務,都需要建立Invoke對象,它是ProxyFactory代理工廠建立的對象,invoke封裝了調用實體,根據scope參數,決定導出服務到本地還是遠端

8. dubbo服務引入

(1)引入時機

① 在spring容器調用ReferenceBean的afterPropertiesSet方法時引用服務,餓漢式的

② 在ReferenceBean對應的服務被注入到其他類中的引用,懶漢式的

預設情況下dubbo使用懶漢式服務,可以通過配置dubbo:reference的init屬性進行重新開機

繼續閱讀