朋友國企幹了5年java,居然不知道Dubbo是做什麼呢?我真信了

2020-08-18 三太子敖丙

前言

接下來一段時間敖丙將帶大家開啟緊張刺激的 Dubbo 之旅!是的要開始寫 Dubbo 系列的文章了,之前我已經寫過一篇架構演進的文章,也說明了微服務的普及化以及重要性,服務化場景下隨之而來的就是服務之間的通信問題,那服務間的通信腦海中想到的就是 RPC,說到 RPC 就離不開咱們的 Dubbo。

這篇文章敖丙先帶著大家來總覽全局,一般而言熟悉一個框架你要先知道這玩意是做什麼的,能解決什麼痛點,核心的模塊是什麼,大致運轉流程是怎樣的。

你要一來就扎入細節之中無法自拔,一波 DFS 直接被勸退的可能性高達99.99%,所以本暖男敖丙將帶大家先過一遍 Dubbo 的簡介、總體分層、核心組件以及大致調用流程

不僅如此我還會帶著大家過一遍如果要讓你設計一個 RPC 框架你看看都需要什麼功能?這波操作之後你會發現嘿嘿 Dubbo 怎麼設計的和我想的一樣呢?真是英雄所見略同啊!

而且我還會寫一個簡單版 RPC 框架實現,讓大家明白 RPC 到底是如何工作的。

如果看了這篇文章你要還是不知道 Dubbo 是啥,我可以要勸退了。

我們先來談一談什麼叫 RPC ,我發現有很多同學不太了解這個概念,還有人把 RPC 和 HTTP 來進行對比。所以咱們先來說說什麼是 RPC。

什麼是 RPC

RPC,Remote Procedure Call 即遠程過程調用,遠程過程調用其實對標的是本地過程調用,本地過程調用你熟悉吧?

想想那青蔥歲月,你在大學趕著期末大作業,正在攻克圖書管理系統,你奮筆疾書瘋狂地敲擊鍵盤,實現了圖書借閱、圖書歸還等等模塊,你實現的一個個方法之間的調用就叫本地過程調用。

你要是和我說你實現圖書館裡系統已經用了服務化,搞了遠程調用了,我只能和你說你有點東西。

簡單的說本機上內部的方法調用都可以稱為本地過程調用,而遠程過程調用實際上就指的是你本地調用了遠程機子上的某個方法,這就是遠程過程調用。

所以說 RPC 對標的是本地過程調用,至於 RPC 要如何調用遠程的方法可以走 HTTP、也可以是基於 TCP 自定義協議。

所以說你討論 RPC 和 HTTP 就不是一個層級的東西。

RPC 框架就是要實現像那小助手一樣的東西,目的就是讓我們使用遠程調用像本地調用一樣簡單方便,並且解決一些遠程調用會發生的一些問題,使用戶用的無感知、舒心、放心、順心,它好我也好,快樂沒煩惱。

如何設計一個 RPC 框架

在明確了什麼是 RPC,以及 RPC 框架的目的之後,咱們想想如果讓你做一款 RPC 框架你該如何設計?

服務消費者

我們先從消費者方(也就是調用方)來看需要些什麼,首先消費者面向接口編程,所以需要得知有哪些接口可以調用,可以通過公用 jar 包的方式來維護接口。

現在知道有哪些接口可以調用了,但是只有接口啊,具體的實現怎麼來?這事必須框架給處理了!所以還需要來個代理類,讓消費者只管調,啥事都別管了,我代理幫你搞定

對了,還需要告訴代理,你調用的是哪個方法,並且參數的值是什麼。

雖說代理幫你搞定但是代理也需要知道它到底要調哪個機子上的遠程方法,所以需要有個註冊中心,這樣調用方從註冊中心可以知曉可以調用哪些服務提供方,一般而言提供方不止一個,畢竟只有一個掛了那不就沒了。

所以提供方一般都是集群部署,那調用方需要通過負載均衡來選擇一個調用,可以通過某些策略例如同機房優先調用啊啥的。

當然還需要有容錯機制,畢竟這是遠程調用,網絡是不可靠的,所以可能需要重試什麼的。

還要和服務提供方約定一個協議,例如我們就用 HTTP 來通信就好啦,也就是大家要講一樣的話,不然可能聽不懂了。

當然序列化必不可少,畢竟我們本地的結構是「立體」的,需要序列化之後才能傳輸,因此還需要約定序列化格式

並且這過程中間可能還需要摻入一些 Filter,來作一波統一的處理,例如調用計數啊等等。

這些都是框架需要做的,讓消費者像在調用本地方法一樣,無感知。

服務提供者

服務提供者肯定要實現對應的接口這是毋庸置疑的。

然後需要把自己的接口暴露出去,向註冊中心註冊自己,暴露自己所能提供的服務。

然後有消費者請求過來需要處理,提供者需要用和消費者協商好的協議來處理這個請求,然後做反序列化

序列化完的請求應該扔到線程池裡面做處理,某個線程接受到這個請求之後找到對應的實現調用,然後再將結果原路返回

註冊中心

上面其實我們都提到了註冊中心,這東西就相當於一個平臺,大家在上面暴露自己的服務,也在上面得知自己能調用哪些服務。

當然還能做配置中心,將配置集中化處理,動態變更通知訂閱者。

監控運維

面對眾多的服務,精細化的監控和方便的運維必不可少。

這點很多開發者在開發的時候察覺不到,到你真正上線開始運行維護的時候,如果沒有良好的監控措施,快速的運維手段,到時候就是睜眼瞎!手足無措,等著挨批把!

那種痛苦不要問我為什麼知道,我就是知道!

小結一下

讓我們小結一下,大致上一個 RPC 框架需要做的就是約定要通信協議,序列化的格式、一些容錯機制、負載均衡策略、監控運維和一個註冊中心!

簡單實現一個 RPC 框架

沒錯就是簡單的實現,上面我們在思考如何設計一個 RPC 框架的時候想了很多,那算是生產環境使用級別的功能需求了,我們這是 Demo,目的是突出 RPC框架重點功能 - 實現遠程調用

所以啥七七八八的都沒,並且我用偽代碼來展示,其實也就是刪除了一些保護性和約束性的代碼,因為看起來太多了不太直觀,需要一堆 try-catch 啥的,因此我刪減了一些,直擊重點。

Let&34;Yo man Hello,I am&34;127.0.0.1", 2333);         service.hello(); 

看起來好像好不錯喲,不過這很是簡陋,用作 demo 有助理解還是極好的!

接下來就來看看 Dubbo 吧!上正菜!

Dubbo 簡介

Dubbo 是阿里巴巴 2011年開源的一個基於 Java 的 RPC 框架,中間沉寂了一段時間,不過其他一些企業還在用 Dubbo 並自己做了擴展,比如當當網的 Dubbox,還有網易考拉的 Dubbok。

但是在 2017 年阿里巴巴又重啟了對 Dubbo 維護。在 2017 年榮獲了開源中國 2017 最受歡迎的中國開源軟體 Top 3。

在 2018 年和 Dubbox 進行了合併,並且進入 Apache 孵化器,在 2019 年畢業正式成為 Apache 頂級項目。

目前 Dubbo 社區主力維護的是 2.6.x 和 2.7.x 兩大版本,2.6.x 版本主要是 bug 修復和少量功能增強為準,是穩定版本。

而 2.7.x 是主要開發版本,更新和新增新的 feature 和優化,並且 2.7.5 版本的發布被 Dubbo 認為是裡程碑式的版本發布,之後我們再做分析。

它實現了面向接口的代理 RPC 調用,並且可以配合 ZooKeeper 等組件實現服務註冊和發現功能,並且擁有負載均衡、容錯機制等。

Dubbo 總體架構

我們先來看下官網的一張圖。

本丙再暖心的給上圖內每個節點的角色說明一下。

節點 角色說明 Consumer 需要調用遠程服務的服務消費方 Registry 註冊中心 Provider 服務提供方 Container 服務運行的容器 Monitor 監控中心

我再來大致說一下整體的流程,首先服務提供者 Provider 啟動然後向註冊中心註冊自己所能提供的服務。

服務消費者 Consumer 啟動向註冊中心訂閱自己所需的服務。然後註冊中心將提供者元信息通知給 Consumer, 之後 Consumer 因為已經從註冊中心獲取提供者的地址,因此可以通過負載均衡選擇一個 Provider 直接調用

之後服務提供方元數據變更的話註冊中心會把變更推送給服務消費者

服務提供者和消費者都會在內存中記錄著調用的次數和時間,然後定時的發送統計數據到監控中心

一些注意點

首先註冊中心和監控中心是可選的,你可以不要監控,也不要註冊中心,直接在配置文件裡面寫然後提供方和消費方直連。

然後註冊中心、提供方和消費方之間都是長連接,和監控方不是長連接,並且消費方是直接調用提供方,不經過註冊中心

就算註冊中心和監控中心宕機了也不會影響到已經正常運行的提供者和消費者,因為消費者有本地緩存提供者的信息。

Dubbo 分層架構

總的而言 Dubbo 分為三層,如果每一層再細分下去,一共有十層。別怕也就十層,本丙帶大家過一遍,大家先有個大致的印象,之後的文章丙會帶著大家再深入。

大的三層分別為 Business(業務層)、RPC 層、Remoting,並且還分為 API 層和 SPI 層。

分為大三層其實就是和我們知道的網絡分層一樣的意思,只有層次分明,職責邊界清晰才能更好的擴展

而分 API 層和 SPI 層這是 Dubbo 成功的一點,採用微內核設計+SPI擴展,使得有特殊需求的接入方可以自定義擴展,做定製的二次開發。

接下來咱們再來看看每一層都是幹嘛的。

  • Service,業務層,就是咱們開發的業務邏輯層。
  • Config,配置層,主要圍繞 ServiceConfig 和 ReferenceConfig,初始化配置信息。
  • Proxy,代理層,服務提供者還是消費者都會生成一個代理類,使得服務接口透明化,代理層做遠程調用和返回結果。
  • Register,註冊層,封裝了服務註冊和發現。
  • Cluster,路由和集群容錯層,負責選取具體調用的節點,處理特殊的調用要求和負責遠程調用失敗的容錯措施。
  • Monitor,監控層,負責監控統計調用時間和次數。
  • Portocol,遠程調用層,主要是封裝 RPC 調用,主要負責管理 Invoker,Invoker代表一個抽象封裝了的執行體,之後再做詳解。
  • Exchange,信息交換層,用來封裝請求響應模型,同步轉異步。
  • Transport,網絡傳輸層,抽象了網絡傳輸的統一接口,這樣用戶想用 Netty 就用 Netty,想用 Mina 就用 Mina。
  • Serialize,序列化層,將數據序列化成二進位流,當然也做反序列化。

SPI

我再稍微提一下 SPI(Service Provider Interface),是 JDK 內置的一個服務發現機制,它使得接口和具體實現完全解耦。我們只聲明接口,具體的實現類在配置中選擇。

具體的就是你定義了一個接口,然後在META-INF/services目錄下放置一個與接口同名的文本文件,文件的內容為接口的實現類,多個實現類用換行符分隔。

這樣就通過配置來決定具體用哪個實現!

而 Dubbo SPI 還做了一些改進,篇幅有限留在之後再談。

Dubbo 調用過程

上面我已經介紹了每個層到底是幹嘛的,我們現在再來串起來走一遍調用的過程,加深你對 Dubbo 的理解,讓知識點串起來,由點及面來一波連連看。

我們先從服務提供者開始,看看它是如何工作的。

服務暴露過程

首先 Provider 啟動,通過 Proxy 組件根據具體的協議 Protocol 將需要暴露出去的接口封裝成 Invoker,Invoker 是 Dubbo 一個很核心的組件,代表一個可執行體。

然後再通過 Exporter 包裝一下,這是為了在註冊中心暴露自己套的一層,然後將 Exporter 通過 Registry 註冊到註冊中心。 這就是整體服務暴露過程。

消費過程

接著我們來看消費者調用流程(把服務者暴露的過程也在圖裡展示出來了,這個圖其實算一個挺完整的流程圖了)。

首先消費者啟動會向註冊中心拉取服務提供者的元信息,然後調用流程也是從 Proxy 開始,畢竟都需要代理才能無感知。

Proxy 持有一個 Invoker 對象,調用 invoke 之後需要通過 Cluster 先從 Directory 獲取所有可調用的遠程服務的 Invoker 列表,如果配置了某些路由規則,比如某個接口只能調用某個節點的那就再過濾一遍 Invoker 列表。

剩下的 Invoker 再通過 LoadBalance 做負載均衡選取一個。然後再經過 Filter 做一些統計什麼的,再通過 Client 做數據傳輸,比如用 Netty 來傳輸。

傳輸需要經過 Codec 接口做協議構造,再序列化。最終發往對應的服務提供者。

服務提供者接收到之後也會進行 Codec 協議處理,然後反序列化後將請求扔到線程池處理。某個線程會根據請求找到對應的 Exporter ,而找到 Exporter 其實就是找到了 Invoker,但是還會有一層層 Filter,經過一層層過濾鏈之後最終調用實現類然後原路返回結果。

完成整個調用過程!

總結

這次敖丙帶著大家先了解了下什麼是 RPC,然後規劃了一波 RPC 框架需要哪些組件,然後再用代碼實現了一個簡單的 RPC 框架。

然後帶著大家了解了下 Dubbo 的發展歷史、總體架構、分層設計架構以及每個組件是幹嘛的,再帶著大夥走了一遍整體調用過程。

我真的是太暖了啊!

dubbo近期我會安排幾個章節繼續展開,最後會出一個面試版本的dubbo,我們拭目以待吧。

我是敖丙,你知道的越多,你不知道的越多,我們下期見!

人才們的 【三連】 就是敖丙創作的最大動力,如果本篇博客有任何錯誤和建議,歡迎人才們留言!

相關焦點

  • 我終於知道什麼是Dubbo了
    在無數個「撐不下去」的時候,我的「治癒系」當然也是學習了!之前有人問我,你用過dubbo嗎?嗯,額,我說,沒了解過。那你知道SpringCloud嗎?嗯,額,我說,我聽說過,好像是微服務用到的一種技術框架。
  • 朋友國企幹了5年安卓,居然不知道Kotlin協程是什麼?
    什麼是協程?官方描述:協程通過將複雜性放入庫來簡化異步編程。程序的邏輯可以在協程中順序地表達,而底層庫會為我們解決其異步性。該庫可以將用戶代碼的相關部分包裝為回調、訂閱相關事件、在不同線程(甚至不同機器)上調度執行,而代碼則保持如同順序執行一樣簡單。
  • 那些年,踩過dubbo的坑。僅此記錄
    遇到這種依賴衝突情況,提供一種暴力解決方法:將本地倉庫刪除相關jar包文件,重新下載依賴文件;由於不跳過單側,構建過程略長,採用了第二種構建方式,如圖靜靜地等待構建。。。(AbstractZookeeperTransporter.java:70) at org.apache.dubbo.remoting.zookeeper.ZookeeperTransporter$Adaptive.connect(ZookeeperTransporter$Adaptive.java) at org.apache.dubbo.configcenter.support.zookeeper.ZookeeperDynamicConfiguration
  • Java Dubbo 框架編譯運行
    從github上倉庫apache/incubator-dubbo下載Dubbo的原始碼,需要系統中已安裝java sdk和maven,java sdk是編譯工具,maven是倉庫依賴管理工具。進入incubator-dubbo目錄,使用maven來編譯軟體包,運行命令mvn package生成軟體包jar文件。
  • 當Dubbo遇上Arthas,會碰撞出什麼樣的火花呢?
    https://alibaba.github.io/arthas/watch.html當線上服務拋出異常時,最著急的是什麼參數導致了拋異常?在demo裡,訪問http://localhost:8080/user/0,UserServiceImpl就會拋出一個異常,因為user id不合法。
  • 面試官:連Serializable都不知道是什麼,你這5年都幹些什麼了?
    張工是一名java程式設計師,工作5年了,一直從事java開發。最近到某網際網路公司面試,做了筆試題後,有一道筆試題是這樣子的:Serializable有什麼作用,張工沒有作答,面談時面試官又問了,張工回答不出個所以然。面試官:你都工作五年了,連序列化都不知道,你這5年都幹些什麼了?張工一臉的無助,不過確實不應該,類似Serializable序列化這樣的知識點,平時應該不會少用。
  • 技術分享——一路踩坑構建Dubbo源碼
    <init>(CuratorZookeeperClient.java:83) at org.apache.dubbo.remoting.zookeeper.curator.CuratorZookeeperTransporter.createZookeeperClient(CuratorZookeeperTransporter.java:26) at org.apache.dubbo.remoting.zookeeper.support.AbstractZookeeperTransporter.connect
  • 過來人聊聊,為什麼java培訓出來的幹不下去
    為什麼java培訓出來的幹不下去為什麼現在很多朋友學完java培訓出來之後找不到工作呢?我們先來看看很多培訓機構是怎麼吹的。01包就業首先很多人去學java是看中了程式設計師的高薪資,以及未來的前景。什麼叫包就業?就是說你培訓結束以後就能馬上得到工作,並且工資一般都能有1W左右。可能不可能呢?現在都什麼社會了,這種天上掉餡餅的事情怎麼還會有人信呢?你學幾個月就馬上有企業要你了,都不需要你自己去找?真實的情況是給你推薦去一些外包公司,一個月也就2.3K塊。並且你不努力的話,2.3K都不一定能拿到。現在的社會2.3K的工作誰找不到嗎?
  • dubbo如何處理業務異常,這個一定要知道哦!
    老顧這裡就不做介紹 但是現在項目都是微服務化的,在使用dubbo構建項目時,會發現provider拋出自定義業務異常,在custom端並不能正確的捕獲。即便我們在provider和custom都有導入相同jar包下面的BusinessException異常,並且拋出這個異常。
  • 看看Dubbo是如何實現的
    大家好,我是java吳彥祖!}}既然知道了容錯的實現流程和邏輯,下面還有一個問題就是如何選擇容錯策略。一般用於可以缺失的非主流程,業務中用的不多;其實的容錯策略直接去官網查看即可,現實業務中基本不可能使用(反正我是除了面試外,沒用到過)。Dubbo中如何自定義集群容錯機制在dubbo中如何進行自定義的集群容錯機制,其實和負載均衡流程是一樣的,畢竟都是基於Dubbo SPI擴展的。
  • 實操塗鴉智能項目,帶你探索Dubbo-go 億級流量
    那麼這些參數是如何從 HTTP API 匹配獲取到的呢?這裡就會用到上文提到的 provider 用於收集元數據的插件。引入插件後,應用在啟動時會掃描需要暴露的 dubbo 接口,將 dubbo 元數據和 HTTP API 關聯。插件使用方法大致如下,這裡調了幾個簡單的配置作為示例,實際生產時註解內容會更多。
  • 反正我收藏了!Apache Dubbo介紹以及擴展機制SPI
    Apache Dubbo 介紹首先我們先問一句,Apahce Dubbo 是什麼?這個問題恐怕我不會給太多答案給你,因為 Dubbo 的官網其實描述非常清楚明了,而且具備了非常全面的架構解析以及源碼解析。所以,學習 Dubbo 非常有必要去 官網傳送門。
  • Beanutils造成dubbo反序列化失敗?
    請求參數我都是拷貝過來的,壓根就沒用Map進行參數傳遞。畢竟我都是個老手了,咋可能犯這樣愚蠢的錯誤。俗話說遇到問題不要慌,讓我們掏出手機先發個朋友圈,不對好像有點跑題了,我們先看一下調用鏈的數據傳遞。❝實際並沒有這樣麻煩,因為在 consumer 做了 rpc 異常攔截,所以我當時看了下 consumer 的日誌就知道是 provider 拋出來的。
  • 阿里資深架構師帶你解密dubbo和zookeeper關係
    廢話不多說,先搭建一個看看是怎麼一回事?–目前對我來說就是,我A工程想調用B工程中的方法怎麼辦?我import不進來啊,這時候我就需要遠程調用的方法了,怎麼遠程調用呢?dobbu給我提供了一個好的開源框架,那我就用它來操作吧!
  • Apache Dubbo反序列化漏洞(CVE-2019-17564)
    有一點在描述中值得注意的,也就是說它影響不只是dubbo,還有spring-web(5.1.9.RELEASE)之前。This vulnerability can affect users using Dubbo-Rpc-Http (2.7.3 or lower) andSpring-Web (5.1.9.RELEASE or lower).
  • 央企、國企和民企最大的區別你知道嗎?
    你中有你,你中有我,命運共同體了。一榮俱榮,一損俱損。國家對外開放了,金球金融危機,國際貿易受阻,單邊主義抬頭。各國正面產業結構自我調整和升級的陣痛,勞動者普遍面臨改行的挑戰。中國對內實行開放,振興中國農村。全國經濟要一體化,消除不平衡,不充分。企業混合制改造是一大趨勢。因為資產要陸續折騰上市。意在剝離銀行不良債務,打好防止金融危機的攻堅戰。
  • 突破Java面試- Dubbo負載均衡及動態代理的策略
    動態代理策略呢?2 考點分析這些都是關於Dubbo必須知道,基本原理,序列化是什麼協議,具體用dubbo的時候,如何負載均衡,如何高可用,如何動態代理等.就是看你對Dubbo掌握程度工作原理:服務註冊,註冊中心,消費者,代理通信,負載均衡網絡通信、序列化:dubbo協議,長連接,NIO,hessian序列化協議負載均衡策略,集群容錯策略,動態代理策略:dubbo跑起來的時候一些功能是如何運轉的,怎麼做負載均衡?怎麼做集群容錯?怎麼生成動態代理?
  • 「DUBBO系列」線程池打滿問題分析方法與實例
    2.3 生產者分析通過分析生產者日誌我們知道生產者線程池被打滿,但是不知道哪一個方法報錯,這就需要結合線程快照進行分析。:13) at sun.reflect.GeneratedMethodAccessor5.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java
  • 由Dubbo直連引出的new File()路徑問題
    -Dcom.alibaba.XxxService=dubbo://localhost:20890 -jar Demo.jar1.4 通過 -D 參數指定映射文件java -Ddubbo.resolve.file=xxx.properties -jar
  • RPC 框架 Dubbo 從理解到使用(一)
    對,這裡我對 SOA 的理解是這樣的。你看,這本 SOA 的書說的和你說的有出入。粒度?SOA 沒有談到這個呀,你這不是 SOA。分層跟 SOA 沒有關係,你為什麼要說這個呢?…Martin 沒辦法,心一橫,老子就叫它 Martin&39;s SOA 太沒品了吧?還是要取個好一點的名字,最好還能跟 SOA 有某種暗示傳承。