偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

徹底搞懂如何通過 ZooKeeper 實現(xiàn)注冊中心

開發(fā) 架構(gòu)
我們針對微服務架構(gòu)中的一個核心技術(shù)組件,即注冊中心的基本模型做了展開,并基于 ZooKeeper 這款分布式協(xié)調(diào)工具重點分析了 Dubbo 中注冊中心的實現(xiàn)方式以及所具備的功能特性。

在微服務架構(gòu)中,注冊中心屬于一種服務治理組件。服務治理的需求來自于服務的數(shù)量,也來自于服務實例的動態(tài)性。在服務相互調(diào)用的過程中,每個服務首先需要高效地找到目標服務才能執(zhí)行遠程調(diào)用,因此服務治理所承載的服務注冊和發(fā)現(xiàn)機制就顯得非常重要了。

而注冊中心就是用來實現(xiàn)服務治理的工具,圍繞注冊中心涉及的角色包括以下三種:

  • 注冊中心:提供服務注冊和發(fā)現(xiàn)機制。
  • 服務提供者:將服務本身注冊到注冊中心,進而暴露服務。
  • 服務消費者:從注冊中心發(fā)現(xiàn)目標服務,進而消費服務。

微服務架構(gòu)中的服務提供者和服務消費者可以認為是注冊中心的客戶端,在服務內(nèi)部都嵌入了客戶端組件。

圖片圖片

上面這張圖所展示的注冊中心基本模型看起來比較簡單,但真正實現(xiàn)起來要考慮的點是非常多的。另一方面,如果想要實現(xiàn)這樣一個注冊中心,我們也需要選擇合適的工具。在今天的課程中,我們選擇的工具是功能、特性都非常適合構(gòu)建注冊中心的 ZooKeeper,讓我們一起來看一下。

ZooKeeper 與注冊中心

ZooKeeper 的物理結(jié)構(gòu)本質(zhì)上就是一個文件系統(tǒng),包含了一系列被稱為 ZNode 的節(jié)點。每一節(jié)點代表位于文件系統(tǒng)中的一個具體物理路徑,用來存儲數(shù)據(jù)。

圖片圖片

如上圖,節(jié)點 count 位于/business/product/count 路徑,節(jié)點 temp 可能存儲著數(shù)據(jù) 100,而節(jié)點/shop/order/1 可能存儲著類似{“id”:“1”,“itemName”:“Notebook”,“price”:“4000”}”這樣的復雜數(shù)據(jù)結(jié)構(gòu)和信息。ZooKeeper 中所有數(shù)據(jù)都是通過 ZNode 的路徑被引用的。

介紹完 ZooKeeper 的基本結(jié)構(gòu),我們來分析為什么它適合實現(xiàn)注冊中心。

事實上,在注冊中心的實現(xiàn)過程中,最復雜的就是變更通知機制,因為它涉及到如何在服務提供者實例狀態(tài)發(fā)生變更時,有效地通知到服務的消費者,從而避免遠程調(diào)用發(fā)生失敗。添加了通知機制的注冊中心模型是這樣的:

圖片圖片

我們知道狀態(tài)變更管理可以采用發(fā)布 - 訂閱模式,具體來說,服務提供者可以根據(jù)服務定義發(fā)布服務,而服務消費者則通過對自己感興趣的服務進行訂閱,并獲取變更后的服務實例信息。

圖片圖片

上圖展示的就是一種服務監(jiān)聽機制。有了這一機制,服務提供者實例的狀態(tài)一旦發(fā)生變化,服務消費者就能第一時間獲取變更通知,從而獲取最新的服務狀態(tài)。

那我們?nèi)绾蝸韺崿F(xiàn)這種監(jiān)聽機制呢?ZooKeeper 為我們提供了現(xiàn)成的解決方案,就是 Watcher 機制。這個 Watcher 機制就相當于上圖中所展示的這種監(jiān)聽器。監(jiān)聽器通過對 ZNode 進行監(jiān)聽,確保了節(jié)點信息發(fā)生變化時能夠?qū)崟r捕捉到這種變化并把它傳遞到客戶端,從而觸發(fā)客戶端的回調(diào)處理函數(shù)。

從實現(xiàn)上講,ZNode 是開發(fā)人員通過代碼操控的主要對象。對 ZNode 的基本操作包括創(chuàng)建節(jié)點、獲取子節(jié)點以及獲取和設置節(jié)點數(shù)據(jù)等。我們可以通過引入 ZooKeeper 的客戶端組件來實現(xiàn)這些操作,常見的客戶端包括自帶的 ZooKeeper API 和第三方 Curator 等。

ZooKeeper 中涉及的主要操作包含了以下 6 種:

圖片圖片

各種工具框架中對 ZooKeeper 的控制基本都是對這些操作的封裝和應用?;?ZooKeeper 各項功能特性實現(xiàn)注冊中心的基本思路如下圖:

圖片圖片

可以看到,無論是服務的提供者還是消費者,在服務初始化時都會與 ZooKeeper 服務器建立連接。然后,圖中所展示的發(fā)布服務定義、注冊新服務、獲取和監(jiān)聽服務地址等操作本質(zhì)上都是對 ZNode 各種基本操作的封裝。當然,作為 ZooKeeper 的客戶端,服務提供者和消費者都需要與 ZooKeeper 保持心跳檢測。

Dubbo 框架默認把 ZooKeeper 作為它的注冊中心實現(xiàn)工具。接下來就讓我們來看看 Dubbo 中的 ZooKeeper 注冊中心。

Dubbo 中的 ZooKeeper 注冊中心

對于 Dubbo 而言,我們首先需要明確保存在 ZNode 中的具體內(nèi)容,這就是服務提供者和消費者的 URL 信息,它們會被分別保存在 ZooKeeper 的/providers 和/consumers 節(jié)點之下。

圖片圖片

同時,服務消費者還會對/providers 節(jié)點進行訂閱。這樣,消費者就能實時獲取提供者的 URL 信息。顯然,這個時候我們會對/providers 節(jié)點添加 Watcher 機制。

我們進一步分析這些注冊信息,可以看到,Dubbo 對各個節(jié)點進行了合理編排,構(gòu)成了 Root、Service、Type、URL 這樣的服務地址分層結(jié)構(gòu)。

圖片圖片

Dubbo 通過對不同層級節(jié)點進行注冊和訂閱,來實現(xiàn)服務地址的發(fā)布和推送。當然,這種分層結(jié)構(gòu)對于我們?nèi)绾谓M織 ZooKeeper 中的數(shù)據(jù)有很好的借鑒意義。

接下來,讓我們來看一些 Dubbo 中的源碼。我們來看一下代表注冊中心的 ZookeeperRegistry 類,而 ZookeeperRegistry 中最重要的就是它的構(gòu)造函數(shù)。這是對應的代碼:

public ZookeeperRegistry(URL url, ZookeeperTransporter, zookeeperTransporter) {
        ...
        //構(gòu)建 Zookeeper 客戶端
     zkClient = zookeeperTransporter.connect(url);
        //添加 Watcher
     zkClient.addStateListener(new StateListener() {
             public void stateChanged(int state) {
                 if (state == RECONNECTED) {
                     try {
                         recover();
                     } catch (Exception e) {
                         logger.error(e.getMessage(), e);
                     }
                 }
             }
         });
 }

不難看出,在 ZookeeperRegistry 的構(gòu)造函數(shù)中,我們通過 ZookeeperClient 客戶端工具創(chuàng)建了與服務器的連接,并且通過 addStateListener 方法添加了監(jiān)聽器。一旦連接發(fā)生重連,就會觸發(fā)回復操作。

為了更好地理解這段代碼,我們需要明確另外兩個核心對象的創(chuàng)建過程。這兩個核心對象分別是前面所展示的 ZookeeperTransporter 和 ZookeeperClient,其中 ZookeeperTransporter 根據(jù)傳入的 URL,通過創(chuàng)建與 Zookeeper 服務器的連接獲取一個 ZookeeperClient 對象,而 ZookeeperClient 則包含了注冊中心運行過程中所有的數(shù)據(jù)操作。

圖片圖片

從功能定位上講,我們可以把 ZookeeperTransporter 看做是一種通信層組件,只負責與 ZooKeeper 實現(xiàn)網(wǎng)絡通信,而 ZookeeperClient 則封裝了所有的注冊中心操作方法,是一種業(yè)務層組件。Dubbo 在這里所采用的這種分層設計思想同樣值得我們借鑒。

目前可以與 ZooKeeper 服務器進行交互的客戶端有很多,Dubbo 提供了對 Zkclient 和 Curator 這兩個客戶端工具的集成,對應的 Transporter 和 ZookeeperClient 實現(xiàn)類如下所示:

圖片圖片

Dubbo 使用 Zkclient 作為其默認實現(xiàn)。

接下來,我們終于到了分析注冊中心具體操作的時候了。ZookeeperRegistry 提供了 doRegister、doUnregister、doSubscribe 和 doUnsubscribe 方法,分別對應注冊、取消注冊、訂閱和取消訂閱這四個具體操作。其中 doRegister 和 doUnregister 這兩個方法比較簡單,只是直接調(diào)用 Zkclient 的 create 和 delete 方法。而 doSubscribe 方法完成服務訂閱操作,代碼比較長,我們提取其中的核心代碼:

ChildListener zkListener = listeners.get(listener);
 if (zkListener == null) {
         listeners.putIfAbsent(listener, new ChildListener() {
                   public void childChanged(String parentPath, List<String>
 currentChilds) {
                        for (String child : currentChilds) {
                             child = URL.decode(child);
                             if (!anyServices.contains(child)) {
                                 anyServices.add(child);
                                     subscribe(url.setPath(child).addParameters(Constants.INTERFACE_KEY, child,Constants.CHECK_KEY, String.valueOf(false)), listener);
                            }
                       }
                   }
             });
         zkListener = listeners.get(listener);
 }

可以看到,Dubbo 會訂閱父級目錄,而當有子節(jié)點發(fā)生變化時就會觸發(fā) ChildListener 中的回調(diào)函數(shù),這個回調(diào)函數(shù)會對這個路徑下的所有子節(jié)點執(zhí)行訂閱操作。

掌握了服務訂閱的實現(xiàn)過程,理解取消訂閱的原理就很簡單了,我們只要去掉 URL 上已經(jīng)注冊的監(jiān)聽器就可以了,doUnsubscribe 方法如下所示:

protected void doUnsubscribe(URL url, NotifyListener listener) {
  ConcurrentMap<NotifyListener, ChildListener> listeners = zkListeners.get(url);
         if (listeners != null) {
             ChildListener zkListener = listeners.get(listener);
             if (zkListener != null) {
                 zkClient.removeChildListener(toUrlPath(url), zkListener);
             }
         }
 }

至此,在 Dubbo 中,如何基于 ZooKeeper 實現(xiàn)注冊中心的實現(xiàn)過程就介紹完了。如果我們想要自己動手實現(xiàn)一個類似的注冊中心,那這個 Dubbo 中的實現(xiàn)過程還是具備很多參考價值的。

總結(jié)

我們來總結(jié)回顧一下這次講的內(nèi)容。我們針對微服務架構(gòu)中的一個核心技術(shù)組件,即注冊中心的基本模型做了展開,并基于 ZooKeeper 這款分布式協(xié)調(diào)工具重點分析了 Dubbo 中注冊中心的實現(xiàn)方式以及所具備的功能特性。

責任編輯:武曉燕 來源: 程序猿技術(shù)充電站
相關(guān)推薦

2025-01-16 00:20:41

2023-02-26 00:00:00

2023-01-30 22:43:39

DubboZooKeeper

2021-01-06 13:52:19

zookeeper開源分布式

2025-04-21 04:00:00

2020-01-10 10:58:34

ZooKeeperEureka注冊中心

2017-12-05 17:44:31

機器學習CNN卷積層

2020-10-14 08:50:38

搞懂 Netty 線程

2025-05-06 01:14:00

系統(tǒng)編程響應式

2025-06-30 00:32:43

策略模式算法MyBatis

2020-06-29 07:58:18

ZooKeeperConsul 注冊中心

2024-01-03 13:39:00

JS,Javascrip算法

2023-10-18 10:55:55

HashMap

2025-04-11 05:55:00

2025-01-13 16:00:00

服務網(wǎng)關(guān)分布式系統(tǒng)架構(gòu)

2021-10-15 08:32:03

RocketMQ數(shù)據(jù)結(jié)構(gòu)架構(gòu)

2023-01-05 07:55:59

Zookeeper服務注冊

2023-05-29 08:12:38

2021-10-09 19:05:06

channelGo原理

2025-03-17 00:21:00

點贊
收藏

51CTO技術(shù)棧公眾號