<ul id="qxxfc"><fieldset id="qxxfc"><tr id="qxxfc"></tr></fieldset></ul>




      注冊(cè)中心作用

      開篇首先想思考一個(gè)問題,沒有注冊(cè)中心 Dubbo 還能玩下去嗎?


      當(dāng)然可以,只要知道服務(wù)提供者地址相關(guān)信息,消費(fèi)者配置之后就可以調(diào)用。如果只有幾個(gè)服務(wù),這么玩當(dāng)然沒問題。但是生產(chǎn)服務(wù)動(dòng)輒成千上百,如果每個(gè)服務(wù)都需要手寫配置信息,想象一下是多么麻煩。


      好吧,如果上面的問題都不是事的話,試想一下如果一個(gè)服務(wù)提供者在運(yùn)行過程中宕機(jī),消費(fèi)者怎么辦?消費(fèi)者不知情,所以它還會(huì)不斷把請(qǐng)求發(fā)往服務(wù)提供者,然后不斷失敗。這個(gè)時(shí)候唯一的辦法就是修改服務(wù)地址信息,然后重啟服務(wù)。


      可以看到如果沒有注冊(cè)中心,分布式環(huán)境中服務(wù)查找發(fā)現(xiàn)將會(huì)非常麻煩,一切需要手工配置,無法完成自動(dòng)化。所以這里就需要一個(gè)第三者,協(xié)調(diào)服務(wù)提供者與消費(fèi)者之間關(guān)系,這就是注冊(cè)中心。

      注冊(cè)中心主要作用如下:

      * 動(dòng)態(tài)加入,服務(wù)提供者通過注冊(cè)中心動(dòng)態(tài)的把自己暴露給消費(fèi)者,無需消費(fèi)者逐個(gè)更新配置文件。
      * 動(dòng)態(tài)發(fā)現(xiàn)服務(wù),消費(fèi)者可以動(dòng)態(tài)發(fā)現(xiàn)新的服務(wù),無需重啟生效。
      * 統(tǒng)一配置,避免本地配置導(dǎo)致每個(gè)服務(wù)配置不一致。
      * 動(dòng)態(tài)調(diào)整,注冊(cè)中心支持參數(shù)動(dòng)態(tài)調(diào)整,新參數(shù)自動(dòng)更新到所有相關(guān)的服務(wù)節(jié)點(diǎn)。
      * 統(tǒng)一管理,依靠注冊(cè)中心數(shù)據(jù),可以統(tǒng)一管理配置服務(wù)節(jié)點(diǎn)。
      注冊(cè)中心工作流程

      注冊(cè)中心工作流程總體比較簡(jiǎn)單,流程圖大致如下:



      主要工作流程可以分為如下幾步:

      * 服務(wù)提供者啟動(dòng)之后,會(huì)將服務(wù)注冊(cè)到注冊(cè)中心。
      * 消費(fèi)者啟動(dòng)之后主動(dòng)訂閱注冊(cè)中心上提供者服務(wù),從而獲取到當(dāng)前所有可用服務(wù),同時(shí)留下一個(gè)回調(diào)函數(shù)。
      * 若服務(wù)提供者新增或下線,注冊(cè)中心將通過第二步的注冊(cè)的回調(diào)函數(shù)通知消費(fèi)者。
      * dubbo-admin(服務(wù)治理中心)將會(huì)會(huì)訂閱服務(wù)提供者以及消費(fèi)者,從而可以在控制臺(tái)管理所有服務(wù)提供者以及消費(fèi)者。
      Dubbo 之前版本主要可以使用 ZooKeeper,Redis 作為注冊(cè)中心 ,而隨著 Dubbo 版本不斷更新,目前還支持
      nacos,consul,etcd 等做為注冊(cè)中心。

      Dubbo 注冊(cè)中心核心源碼

      ps: 以下源碼基于 dubbo 2.7.3 版本

      注冊(cè)中心實(shí)現(xiàn)使用模板模式,源碼位于 dubbo-registry 模塊,類關(guān)系如下圖:



      最上層的 RegistryService 接口定義了核心方法,分別為注冊(cè),取消注冊(cè),訂閱,取消訂閱以及查詢。



      中間層抽象類主要實(shí)現(xiàn)通用邏輯,如:AbstractRegistry 實(shí)現(xiàn)緩存機(jī)制,F(xiàn)ailbackRegistry 實(shí)現(xiàn)失敗重試功能。

      底層 ZookeeperRegistry等為具體實(shí)現(xiàn)類,實(shí)現(xiàn)與 ZooKeeper 等注冊(cè)中心交互的邏輯。

      接下去我們具體分析 AbstractRegistry 與 FailbackRegistry 邏輯。

      AbstractRegistry 緩存實(shí)現(xiàn)的原理

      如果每次服務(wù)調(diào)用都需要調(diào)用注冊(cè)中心實(shí)時(shí)查詢可用服務(wù)列表,不但會(huì)讓注冊(cè)中心承受巨大的流量壓力,還會(huì)產(chǎn)生額外的網(wǎng)絡(luò)請(qǐng)求,導(dǎo)致系統(tǒng)性能下降。

      其次注冊(cè)中心需要非強(qiáng)依賴,其宕機(jī)不能影響正常的服務(wù)調(diào)用。

      基于以上幾點(diǎn),注冊(cè)中心模塊在 AbstractRegistry 類中實(shí)現(xiàn)通用的緩存機(jī)制。這里的緩存可以分為兩類,內(nèi)存服務(wù)緩存以及磁盤文件緩存。

      內(nèi)存服務(wù)緩存

      內(nèi)存服務(wù)緩存很好理解也最容易實(shí)現(xiàn),AbstractRegistry使用一個(gè) ConcurrentMap保存相關(guān)信息。
      private final ConcurrentMap<URL, Map<String, List<URL>>> notified = new
      ConcurrentHashMap<>();
      這個(gè)集合中 key 為消費(fèi)者的 URL,而 value 為一個(gè) Map 集合。這個(gè)內(nèi)層 Map 集合使用服務(wù)目錄作為 key,分別為
      providers,routers,configurators,consumers 四類,value 則是對(duì)應(yīng)服務(wù)列表集合。

      磁盤文件緩存

      由于服務(wù)重啟就會(huì)導(dǎo)致內(nèi)存緩存消失,所以額外增加磁盤文件緩存。

      文件緩存默認(rèn)位置位于 ${user.home}/.dubbo/文件夾,文件名為
      dubbo-registry-${application.name}-${register_address}.cache。可以設(shè)置
      dubbo.registry.file 配置信息從而修改默認(rèn)配置,實(shí)現(xiàn)源碼如下:
      String filename = url.getParameter(Constants.FILE_KEY,
      System.getProperty("user.home") + "/.dubbo/dubbo-registry-" +
      url.getParameter(Constants.APPLICATION_KEY) + "-" + url.getAddress() +
      ".cache");
      ps: ${application.name} 取自 dubbo.application.name 信息,${register_address}
      取值注冊(cè)中心地址信息。緩存文件完整名稱為:
      C:\Users\xxx/.dubbo/dubbo-registry-dubbo-auto-configure-consumer-sample-127.0.0.1:2181.cache

      緩存文件內(nèi)容使用 properties 配置文件格式,即 key=value 格式。key為服務(wù)接口名稱,value
      為服務(wù)列表,由于服務(wù)可能存在多個(gè),將會(huì)使用空格分隔。

      緩存文件的加載

      dubbo 程序初始化的時(shí)候,AbstractRegistry 構(gòu)造函數(shù)將會(huì)從本地磁盤文件中將數(shù)據(jù)讀取到 Properties 對(duì)象實(shí)例中,后續(xù)都將會(huì)先寫入
      Properties,最后再將里面信息再寫入文件。

      緩存初始化的源碼為下圖。



      緩存文件的保存與更新

      緩存文件將會(huì)通過 AbstractRegistry#notify 方法保存或更新。客戶端第一次訂閱服務(wù)獲取的全量數(shù)據(jù),或者后續(xù)回調(diào)中獲取到新數(shù)據(jù),都將會(huì)調(diào)用
      AbstractRegistry#notify 方法,用來更新內(nèi)存緩存以及文件緩存。

      notify 方法源碼如下圖:



      在保存文件緩存方法中,首先把根據(jù) URL 取出的數(shù)據(jù),拼接成字符串,然后寫入上面提到過的 properties 對(duì)象中,最后輸出到文件中。

      這里可以選擇兩種保存方式,同步或異步。由于 notify 可能被多次調(diào)用,為了提高系統(tǒng)能,系統(tǒng)默認(rèn)使用異步方式保存。

      saveProperties 方法源碼如下:



      doSaveProperties 方法最終將會(huì)將信息寫入緩存??紤]到保存方法可能會(huì)被多個(gè)線程同時(shí)調(diào)用,這里使用 CAS
      方法,首先比較版本大小,若小于,代表有新線程正在寫入信息,本次更新直接丟棄。

      其次考慮到多個(gè) dubbo 應(yīng)用可能共用一份緩存文件,所以這里使用文件排他鎖當(dāng)做分布式鎖,防止多個(gè)應(yīng)用并發(fā)操作同一份文件。

      一旦文件寫入異?;蛘攉@取鎖失敗,保存操作將會(huì)不斷重試,直到超過最大次數(shù)。

      ps: dubbo 2.7.2 之前重試沒有設(shè)置最大次數(shù),如果文件沒有權(quán)限保存,保存將會(huì)一直失敗,異步線程將會(huì)陷入死循環(huán)。

      doSaveProperties 方法源碼如下:



      FailbackRegistry 重試機(jī)制

      FailbackRegistry 繼承 AbstractRegistry,實(shí)現(xiàn)了 register,subscribe等通用法,并增加 doRegister,
      doSubscribe 等模板方法,交由子類實(shí)現(xiàn)。

      如果 doRegister 等模板方法發(fā)生異常,會(huì)將失敗任務(wù)放入集合,然后定時(shí)再次調(diào)用模板方法。

      FailbackRegistry 失敗重試集合分別為:



      以 subscribe 方法為例,這里將會(huì)調(diào)用這些 doSubscribe
      的模板方法。如果發(fā)生異常將會(huì)讀取緩存文件中內(nèi)容,然后加載服務(wù)。最后新建異步定時(shí)任務(wù)加入重試集合中,然后由定時(shí)器去重試這些任務(wù)。

      FailbackRegistry#subscribe 方法源碼:



      在 addFailedSubscribed 中將會(huì)新建定時(shí)任務(wù),然后交由定時(shí)器執(zhí)行。定時(shí)任務(wù)默認(rèn)最大重試次數(shù)為 3 次,調(diào)用時(shí)間間隔默認(rèn)為 5 s。

      addFailedSubscribed 源碼如下:



      其他失敗重試任務(wù)都比較類似,全都繼承自 AbstractRetryTask 父類,類關(guān)系如下圖。



      總結(jié)

      本文主要講述注冊(cè)中心作用,工作流程,通用緩存機(jī)制以及失敗重試機(jī)制。從中可以學(xué)到模板模式,以及多線程并發(fā)技巧。

      這里沒有涉及到具體注冊(cè)中心實(shí)現(xiàn),由于目前最主要使用 ZooKeeper 作為注冊(cè)中心,所以下篇將會(huì)聊聊 ZooKeeper 注冊(cè)中心原理,敬請(qǐng)期待。

      幫助書籍

      『深入理解 Apache Dubbo 與實(shí)戰(zhàn)』


      友情鏈接
      ioDraw流程圖
      API參考文檔
      OK工具箱
      云服務(wù)器優(yōu)惠
      阿里云優(yōu)惠券
      騰訊云優(yōu)惠券
      京東云優(yōu)惠券
      站點(diǎn)信息
      問題反饋
      郵箱:[email protected]
      QQ群:637538335
      關(guān)注微信

        <ul id="qxxfc"><fieldset id="qxxfc"><tr id="qxxfc"></tr></fieldset></ul>
          国产精品无码久黑人无码牛牛久久 | 秋霞福利片 | poronovideo白嫩少妇 | 日本免费一曲二曲三曲的起源 | 屄在线| 99热这里只有精品久久 | 中国操逼网 | 男女羞羞视频免费观看 | 李美淑的r级无删减 | 国内视频精品在线 |