13. Dubbo原理解析-註冊中心之Zookeeper協議註冊中心

下面我們來看下開源dubbo推薦的業界成熟的zookeeper做爲註冊中心, zookeeper是hadoop的一個子項目是分佈式系統的可靠協調者,他提供了配置維護,名字服務,分佈式同步等服務。對於zookeeper的原理本文檔不分析,後面有時間在做專題。

zookeeper註冊中心

Zookeeper對數據存儲類似linux的目錄結構,下面給出官方文檔對dubbo註冊數據的存儲示例

 

假設讀者對zookeeper有所瞭解,能夠搭建zookeeper服務,其實不瞭解也沒關係,谷歌百度下分分鐘搞起。

作爲測試調試dubbo,我是在本地起的zookeeper


指定zookeeper配置文件地址


配置文件中兩個關鍵參數:

dataDir zookeeper存儲文件的地址

clientPort 客戶端鏈接的端口號

 

Dubbo服務提供者配置

<dubbo:registry protocol=”zookeeper” address="127.0.0. 1:2181" />

<beanid="demoService" class="com.alibaba.dubbo.demo.provi der.DemoServiceImpl"/>

<dubbo:serviceinterface="com.alibaba.dubbo.demo.DemoServi ce" ref="demoService"/>

除了配置註冊中心的,其他都一樣

 

Dubbo服務消費者配置

<dubbo:registry protocol=”zookeeper” address="127.0.0. 1:2181" />

<dubbo:referenceid="demoService"interface="com.alibaba.dubbo.demo.DemoService"/>

除了配置註冊中心的,其他都一樣

  

客戶端獲取註冊器

服務的提供者和消費者在RegistryProtocol利用註冊中心暴露(export)和引用(refer)服務的時候會根據配置利用Dubbo的SPI機制獲取具體註冊中心註冊器

Registry registry = registryFactory.getRegistry(url);

這裏的RegistryFactory是ZookeeperRegistryFactory看如下工廠代碼

public class ZookeeperRegistryFactory extends AbstractRegistryFactory {

    public Registry createRegistry(URL url) {

        return new ZookeeperRegistry(url, zookeeperTransporter);

    }

}

這裏創建zookeepr註冊器ZookeeperRegistry

ZookeeperTransporter是操作zookeepr的客戶端的工廠類,用來創建zookeeper客戶端,這裏客戶端並不是zookeeper源代碼的自帶的,而是採用第三方工具包,主要來簡化對zookeeper的操作,例如用zookeeper做註冊中心需要對zookeeper節點添加watcher做反向推送,但是每次回調後節點的watcher都會被刪除,這些客戶會自動維護了這些watcher,在自動添加到節點上去。

接口定義:

@SPI("zkclient")

public interface ZookeeperTransporter {

    @Adaptive({Constants.CLIENT_KEY, Constants.TRANSPORTER_KEY})

    ZookeeperClient connect(URL url);

}

默認採用zkClient, dubbo源碼集成兩種zookeeper客戶端,除了zkClient還有一個是curator

 

 

ZookeeperRegistry註冊器的實現

1.構造器利用客戶端創建了對zookeeper的連接,並且添加了自動回覆連接的監聽器。

zkClient = zookeeperTransporter.connect(url);

    zkClient.addStateListener(new StateListener() {

            public void stateChanged(int state) {

                if (state ==RECONNECTED)

                   recover();

          }

});

2.註冊url就是利用客戶端在服務器端創建url的節點,默認爲臨時節點,客戶端與服務端斷開,幾點自動刪除

zkClient.create(toUrlPath(url),url.getParameter(Constants.DYNAMIC_KEY,true));      

3.取消註冊的url,就是利用zookeeper客戶端刪除url節點

zkClient.delete(toUrlPath(url));

4. 訂閱url, 功能是服務消費端訂閱服務提供方在zookeeper上註冊地址,這個功能流程跟DubboRegister不一樣, DubboRegister是通過Dubbo註冊中心實現SimpleResgiter在註冊中心端,對url變換、過濾篩選然後將獲取的provierUrl(提供者ulr)利用服務消費者暴露的服務回調在refer。

由於這裏註冊中心採用的是zookeeper,zookeeper不可能具有dubbo的業務邏輯,這裏對訂閱的邏輯處理都在消費服務端訂閱的時候處理。

1) 對傳入url的serviceInterface是*代表訂閱url目錄下所有節點即所有服務,這個註冊中心需要訂閱所有

2) 如果指定了訂閱接口通過toCategoriesPath(url)轉換需要訂閱的url

如傳入url consumer://10.33.37.8/com.alibaba.dubbo.demo.DemoService?application=demo-consumer&category=providers,configurators,routers&dubbo=2.5.4-SNAPSHOT&interface=com.alibaba.dubbo.demo.DemoService&methods=sayHello&pid=4088&side=consumer&timestamp=1417405597808

轉換成urls

/dubbo/com.alibaba.dubbo.demo.DemoService/providers,/dubbo/com.alibaba.dubbo.demo.DemoService/configurators, /dubbo/com.alibaba.dubbo.demo.DemoService/routers

3) 設配傳入的回調接口NotifyListener,轉換成dubbo對zookeeper操作的ChildListener

4)以/dubbo/com.alibaba.dubbo.demo.DemoService/providers爲例創建節點zkClient.create(path, false);

但是一般情況下如果服務提供者已經提供服務,那麼這個目錄節點應該已經存在,Dubbo在Client層屏蔽掉了創建異常。

5) 以/dubbo/com.alibaba.dubbo.demo.DemoService/providers爲例給節點添加監聽器,返回所有子目錄

List<String> children = zkClient.addChildListener(path, zkListener);

        if (children !=null) {urls.addAll(toUrlsWithEmpty(url, path,hildren));}

        toUrlsWtihEmpty用來配置是不是需要訂閱的url,是加入集合

6) 主動根據得到服務提供者urls回調NotifyListener,引用服務提供者生成invoker可執行對象

5. 取消訂閱url, 只是去掉url上的註冊的監聽器
發佈了69 篇原創文章 · 獲贊 99 · 訪問量 46萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章