Dubbo的設計理念原來就藏在這三張圖中

2021-02-13 OSC開源社區

Dubbo在眾多的微服務框架中脫穎而出,佔據RPC服務框架的半壁江山,非常具有普適性,熟練掌握 Dubbo的應用技巧後深刻理解其內部實現原理,讓大家能更好的掌控工作,助力職場,特別能讓大家在面試中脫穎而出。

那Dubbo內部的設計理念,實現原理是什麼呢?

本文將結合官方提供的3張圖,從如下三個方面介紹其內部的核心實現、以及如何指導實踐。

在Dubbo中存在4類角色:

Registry 註冊中心。

Consumer 服務調用者、消費端。

Provider 服務提供者。

Monitor 監控中心。

具體的交互流程包括如下關鍵步驟:

服務提供者在啟動的時候向註冊中心進行註冊。

消息消費者在啟動的時候向註冊中心訂閱指定服務,註冊中心將以某種機制(推或拉)模式告知消費端服務提供者列表。

當服務提供者數量變化(服務提供者擴容、縮容、宕機等因素),註冊中心需要以某種方式(推或拉)告知消費端,以便消費端進行正常的負載均衡。

服務提供者、服務消費者向監控中心匯報TPS等調用數據,以便監控中心進行可視化展示等。

Dubbo官方提供了多種註冊中心,接下來將以使用最為普遍的Zookeeper進一步介紹註冊中心的原理。

首先我們來看一下Zookeeper註冊中心中的數據存儲目錄結構,從目錄結構來窺探其實現機制。 

Dubbo Zookeeper註冊中心,其目錄組織結構為 /dubbo/{ServiceName},再每一個服務名稱下會有4個目錄:

基於Zookeeper註冊中心的實現細節如下:

服務提供者啟動時會向註冊中心註冊,主要是在對應服務的providers目錄下增加一條記錄(臨時節點),同時監聽 configurators節點。

服務消費者啟動時會向註冊中心訂閱,主要是在對應服務的consumers目錄下增加一條記錄(臨時節點),同時監聽 configurators、routers 目錄。

由於當有新的服務提供者上線後 providers 目錄會增加一條記錄,消費者能立馬收到一個服務提供者列表變化的通知,得以將最新的服務提供者列表推送給服務調用方(消費端);如果一個服務提供者宕機,由於創建的節點是臨時節點,Zookeeper會將該節點移除,同樣會觸發事件,消費端得知最新的服務提供者列表,從而實現路由的動態註冊與發現。

當Dubbo新版本上線後,如果需要進行灰度發布,可以通過dubbo-admin等管理平臺添加路由規則,最終會寫入到指定服務的router節點(持久節點),服務調用方會監聽該節點的變化,從而感知最新的路由規則,將其用於服務提供者的篩選,從而實現灰度發布等功能。

configurators 節點的運作機制與 router 節點一樣,就不重複介紹。

擴展思考:

1、如果註冊中心全部宕機,對整個服務體系會有什麼影響?

如果整個註冊中心全部宕機,整個服務調用能正常工作,不會影響現有的服務消費者調用,但消費端無法發現新註冊的服務提供者。

2、如果註冊中心內存溢出或頻繁發生 Full Gc,對整個集群又會帶來什麼影響呢?

如果頻繁發生Full GC,並且如果Full GC的時間超過了Zookeeper會話的過期時間,將會造成非常嚴重的影響,會觸發所有臨時節點被刪除,消費端將無法感知服務提供者的存在,影響服務調用,將大面積拋出 No provider 等錯誤。正所謂成也臨時節點、敗也臨時節點。

為了避免Full Gc帶來的嚴重後果,用於Dubbo註冊中心的Zookeeper,一定會要獨享,並及時做好內存、CPU等的監控與告警。

Dubbo的服務調用設計十分優雅,其實現原理如下圖所示: 

服務調用,重點闡述客戶端發起一個RPC服務調用時的所有實現細節,包括服務發現、故障轉移、路由轉發、負載均衡等方面,是Dubbo實現灰度發布的理論基礎。

2.1 服務發現

客戶端在向服務端發起請求時,首先需要知道的是當前有哪些可用的服務提供者,通常有兩種服務發現機制:

靜態化配置 不妨回想一下,在Dubbo等微服務框架出現之前,一個模塊調用另外一個模塊通常的做法是使用一個配置文件,將服務提供的列表配置配置在配置文件中,客戶端從按照配置文件中的列表進行淪陷。

其弊端也非常明顯:如果需要調用的服務眾多,配置文件會變得臃腫,對擴容縮容的管理、機器宕機等變更不友好,管理非常困難。

動態發現

通常基於註冊中心實現服務的註冊與動態發現,由於上文已詳細介紹,在這裡就不累述。

2.2 負載均衡

客戶端通過服務發現機制,能動態發現當前存活的服務提供者列表,接下來要考慮的是如果從服務提供者列表中選擇一個服務提供者發起調用,這就是所謂的負載均衡,即 LoadBalance。

在Dubbo中默認提供了隨機、加權隨機、最少活躍連接、一致性Hash等負載均衡算法。

2.3 路由機制

其實Dubbo中不僅提供了負載均衡機制,還提供了智能路由機制,這是實現Dubbo灰度發布的理論基礎。

所謂的路由機制,是在服務提供者列表中,再設置一定的規則,進行過濾選擇,負載均衡時只從路由過濾規則篩選出來的服務提供者列表中選擇,為了更加形象的闡述路由機制的工作原理,給出如下示意圖:

 上述設置了一條路由規則,即查詢機構ID為102的查詢用戶請求信息,請發送到新版本,即192168.3.102上,那主要在進行負載均衡之前先執行路由規則,從原始的服務提供者列表者按照路由規則進行過濾,從中挑選出符合要求的提供者列表,然後再進行負載均衡。

路由機制的核心理念:在進行負載均衡之前先對服務提供者列表運用路由規則,得出一個參與負載均衡的提供者列表。

2.4 故障轉移

遠程服務調用通常涉及到網絡等因素,客戶端向服務提供者發起RPC請求調用時並不一定100%成功,當調用失敗後該採用何種策略呢?

Dubbo提供了如下策略:

failover 失敗後選擇另外一臺服務提供者進行重試,重試次數可配置,通常適合實現冪等服務的場景。

failfast

快速失敗,失敗後立即返回錯誤。

failsafe 調用失敗後列印錯誤日誌,返回成功,通常用於記錄審計日誌等場景。

failback 調用失敗後,返回成功,但會在後臺定時無限次重試,重啟後不再重試。

forking 並發調用,收到第一個響應結果後返回給客戶端。通常適合實時性要求比較高的場景,但浪費伺服器資源,通常可以通過forks參數設置並發調用度。

Dubbo的通信線程模型入下圖所示: 

3.1 網絡通信協議

網絡傳輸通常需要自定義通信協議,通常採用 Header + Body 的協議設計理念,並且 Header 長度固定,並且包含一個長度欄位,用於記錄整個協議包的大小。

網絡傳輸為了提高傳輸效率,可以採取對傳輸數據進行壓縮,通常是對 body 進行序列化與壓縮。

Dubbo支持目前支持 java、compactedjava、nativejava、fastjson、fst、hessian2、kryo等序列化協議。

3.2 線程派發機制

在Dubbo中默認會創建200個線程用於處理業務方法,所謂的線程派發機制就是IO線程如何決定何種請求轉發到哪類線程中執行。

目前Dubbo中所有的心跳包、網絡讀寫在IO線程中執行,無法通過配置進行修改。

Dubbo提供了如下幾種線程派發機制(Dispatcher):

all 所有的請求轉發到業務線程池中執行(除IO讀寫、心跳包)

message 只有請求事件在線程池中執行,其他在IO線程上執行。

connection 請求事件在線程池中執行,連接、斷開連接事件排隊執行(含一個線程的線程池)。

direct

所有請求直接在IO線程中執行。

> 溫馨提示:有關線程模型,網絡通信模式,可以參考如下內容。

線程派發機制之所有會有多種策略,主要是考慮線程切換帶來的開銷是否能容忍,即線程切換帶來的開銷小於多線程處理帶來的提升。

例如在Dubbo中,對心跳包只需直接返回PONG包(OK),邏輯非常簡單,如果將其轉換到業務線程池,並不能帶來性能提升,反而因為需要線程切換,帶來性能損耗,故在IO線程中直接發送響應包是一個非常可取的做法。

在網絡編程中需要遵循一條最佳實踐:IO線程中不能有阻塞操作,阻塞操作需要轉發到業務線程池。

相關焦點

  • eBay鄧明:dubbo-go 中 metrics 的設計
    今天這篇文章將會從比較大的概念和抽象上討論一下 dubbo-go 中的 metrics 模塊的設計——實際上也就是 Dubbo 中的 metrics 的設計。因為我僅僅是將 Dubbo 裡面的相關內容在 dubbo-go 中複製一份。目前 dubbo-go 的 metrics 剛剛開始起步,第一個 PR ,點擊這裡。
  • Dubbo 版 Swagger 來啦!Dubbo-Api-Docs 發布
    >如果 dubbo 提供者的接口和方法參數在一個單獨的 jar 項目中,則在該項目中引入: dubbo-api-docs-annotations。下面我們在這兩個子模塊中增加 Dubbo-Api-Docs:<dependency> <groupId>org.apache.dubbo</groupId> <artifactId>dubbo-api-docs-annotations</artifactId> <version
  • 告訴你 Dubbo 的底層原理,面試不再怕!
    所以這裡我們需要每個服務都需要提供接口出來,在發起服務調用執勤,會創建一個動態代理對象,在我們的消費者中只有一個接口,我們可以認為動態代理類相當於為這個接口動態的創建一個實體類出來,然後用動態帶來對象進行接口調用。
  • SpringBoot+ Dubbo + Mybatis + Nacos +Seata整合來實現Dubbo分布式事務
    standalone1在瀏覽器打開Nacos web 控制臺:http://192.168.10.200:8848/nacos/index.html輸入nacos的帳號和密碼 分別為nacos:nacos這是時候
  • Spring Cloud與Dubbo優缺點詳解
    從系統結構簡易程度考慮Spring Cloud的系統結構更簡單,「註冊+springmvc=springcloud」,而 Dubbo 各種複雜的 URL、protocol、register、invocation、dubbofilter、dubboSPI,dubbo
  • Java Dubbo 框架編譯運行
    從github上倉庫apache/incubator-dubbo下載Dubbo的原始碼,需要系統中已安裝java sdk和maven,java sdk是編譯工具,maven是倉庫依賴管理工具。進入incubator-dubbo目錄,使用maven來編譯軟體包,運行命令mvn package生成軟體包jar文件。
  • 40張圖帶你看懂分布式追蹤系統原理及實踐
    :Trace 的全局上下文信息, 如裡面有traceId理解這三個概念非常重要,為了讓大家更好地理解這三個概念,我特意畫了一張圖理解了這三個概念,接下來我看看分布式追蹤系統如何採集統一圖中的微服務調用鏈
  • Dubbo Metrics 發布新版本 2.0.1 | Dubbo 的度量統計基礎設施
    和dubbo.provider.DemoService.rt。由於 metric 數據具有天然的時間序列屬性,因此數據非常適合存儲到時間序列資料庫當中,要統計所有的 Dubbo 服務的 QPS,那麼就需要查找所有名稱為dubbo.provider.*.qps的指標,然後對他們進行求和。由於涉及到模糊搜索,這對於絕大部分資料庫的實現都是比較費時的。如果要統計更加詳細的 Dubbo 方法級別的 QPS 和 RT,那麼實現上就會更加複雜了。
  • 史上最全 40 道 Dubbo 面試題及答案,看完碾壓面試官
    Dubbo 更是中高級面試過程中經常會問的技術,無論你是否用過,你都必須熟悉。 下面我為大家準備了一些 Dubbo 常見的的面試題,一些是我經常問別人的,一些是我過去面試遇到的一些問題,總結給大家,希望對大家能有所幫助。 1、Dubbo是什麼?
  • 火了近十年的阿里開源項目 Apache Dubbo...
    不過,Dubbo 服務與 Dubbo Service 之間並不存在強綁定關係,換言之,某個 Dubbo 服務也能部署在多個 Dubbo Services 中,因此,Dubbo 服務與 Service 數量關係是 N 對 M(N, M >= 1),如下圖所示:圖 3上圖中 P1 Service 到 P3 Service 為 Dubbo Service
  • 這三張圖裡,藏著100多個漢字,找到50個就是高智商
    以下3張圖中,你能找出多少個漢字?能找到30個以上的都是漢字達人,找到50個就是高智商,據說這裡面一共藏著100個漢字以上,你能找出來嗎?第一張圖:第二張圖:第三張圖:經過了一番頭腦風暴,讓我們來放鬆一下,接下來為大家整理了筆畫最多的漢字,這些都是輸入法可以打出來的,按照筆畫數目為大家整理。
  • 三張吃雞地圖哪張上分最快?網友:這張圖跑毒只需1分鐘!
    荒野行動目前一共有三張地圖可供玩家選擇,分別是激戰原野、颶風半島和都市陣線。三張地圖類型差別非常大,不過要說哪張地圖最容易上分,而且玩家數量最多,那小編認為還要數最老的那張激戰原野了!最新推出的都市陣線,它是仿造日本京都的城市構造設計的。雖然它的面積和激戰原野差不多,不過由於都市陣線中到處是各種高樓大廈,所以真正發生激烈交火的情況並不多。這張地圖出現後最高興的應該就是那些資深的LYB和伏地魔們了,偷偷藏在樓頂或者電梯等地方,趁你一不注意就會送你回老家!
  • 官方Dubbo Spring Boot Starter 1.0.0 公測版即將發布
    據阿里開發團隊宣布,Dubbo Spring Boot Starter 1.0.0 公測版已開發完畢,即將發布至 Maven 公有倉庫,目前正在內部測試中。
  • 「撲克牌制勝術」揭秘 圖中藏貓膩英文字母(圖)
    「撲克牌制勝術」揭秘 圖中藏貓膩英文字母(圖)   例如,在這副撲克牌中,「4」的背面單詞中的第四個字母是「U」;「7」的背面單詞的第四個字母就變成了「T」;「9」的背面單詞的第四個字母是「G」;「10」的背面單詞的第四個字母是「O」。其他的「J、Q、K」的背面單詞的第四個字母也就是「J、Q、K」。而背面單詞的第四個字母一旦變成了「X」、「W」,就意味著這張牌是「王」。
  • 當當網開源 Dubbox,擴展 Dubbo 服務框架支持REST風格遠程調用
    中舊版本的嵌入式Jetty,可以顯著的提高REST等的遠程調用性能,並將Servlet API的支持從2.5升級到3.1。(註:除了REST,dubbo中的WebServices、Hessian、HTTP Invoker等協議都基於這個HTTP remoting體系)。 升級Spring:將dubbo中Spring由2.x升級到目前最常用的3.x版本,減少項目中版本衝突帶來的麻煩。
  • 小時候電視機經常出現的這張圖是什麼意思 模式圖設計其實非常精密...
    小時候電視機經常出現的這張圖是什麼意思 模式圖設計其實非常精密和嚴謹時間:2018-05-04 07:31   來源:錢江晚報   責任編輯:凌君 川北在線核心提示:原標題:小時候電視機經常出現的這張圖是什麼意思 模式圖設計其實非常精密和嚴謹 不知道大家小時候有沒有在電視上看見過這張圖?
  • Dubbo系列-揚帆起航
    不僅如此我還會帶著大家過一遍如果要讓你設計一個 RPC 框架你看看都需要什麼功能?這波操作之後你會發現嘿嘿 Dubbo 怎麼設計的和我想的一樣呢?真是英雄所見略同啊!而且我還會寫一個簡單版 RPC 框架實現,讓大家明白 RPC 到底是如何工作的。
  • 塗鴉·少女心·背景圖:龍應當藏在雲裡,你應當藏在心裡
    今天給小夥伴們帶來的是塗鴉少女心背景圖哦,喜歡的話就趕緊收藏起來吧!圖中是一句很唯美的句子,然後周圍是超級可愛的塗鴉圖案,整體看起來滿滿的都是少女心,非常適合用來當作背景圖呢!龍應當藏在雲裡,你應當藏在心裡,因為把愛的人藏在心裡的話,整個人就會充滿了甜蜜。再看這張背景圖的設計也很不錯,有天使翅膀還有太陽,到處都散發著美好的氣息,而且喜歡的話可以和對象一起用哦!這張背景圖光是看著都覺得很喜歡了,上面的每一個小點綴都那麼的可愛甜美,真的有種萬物皆甜的味道。
  • 《我的世界》強迫症「無法直視」5張圖,圖三你的良心不會痛麼?
    《我的世界》強迫症「無法直視」的5張圖,不信你來試試?MC強迫症玩家是一個龐大的玩家群體,Minecraft設計師們,你們的這些設計,自己心裡不會難受麼?你們的良心不會痛麼?一個靈魂沙方塊有三個人臉,但是這人臉的材質有大有小,參差不齊,這樣的材質是誰做出來的?完全沒有對稱美!強迫症表示非常想把這幾個臉給擰下來!據說這是被Him囚禁於靈魂沙方塊中的靈魂,玩家走在靈魂沙上會受到怨靈的影響,所以行動速度才會遲緩。只是這三張臉這麼秀,靈魂沙你知道麼?
  • 《天官賜福》動畫用這三張概念場景圖,描繪了謝憐的人生經歷
    官網中有動畫最新資訊以及一些海報福利,感興趣的小夥伴可以去b站自行搜索。在官網分享的圖中,有三張動畫概念場景圖,都是天官中的名場面,分別代表謝憐人生的三個階段,富有意義。畫師:藏野九十九神武街太子悅神「太子悅神」是仙樂國史上,最空前絕後的一次上元祭天遊。因為作為悅神武者的謝憐,是仙樂有史以來,最備受矚目、實力最強的太子。