黄色网址大全免费-黄色网址你懂得-黄色网址你懂的-黄色网址有那些-免费超爽视频-免费大片黄国产在线观看

專注Java教育14年 全國咨詢/投訴熱線:400-8080-105
動力節(jié)點LOGO圖
始于2009,口口相傳的Java黃埔軍校
首頁 hot資訊 Dubbo注冊中心分析

Dubbo注冊中心分析

更新時間:2021-09-08 12:01:17 來源:動力節(jié)點 瀏覽1476次

注冊中心

關于注冊中心,Dubbo提供了多個實現(xiàn)方式,有比較成熟的使用zookeeper 和 redis 的實現(xiàn),也有實驗性質(zhì)的Multicast實現(xiàn)。

Zookeeper是Apacahe Hadoop的子項目,是一個樹型的目錄服務,支持變更推送,適合作為Dubbo服務的注冊中心,工業(yè)強度較高,可用于生產(chǎn)環(huán)境,

所以Zookeeper注冊中心也是Dubbo推薦使用也是使用度比較高的注冊中心。

Zookeeper注冊中心支持以下功能:

當提供者出現(xiàn)斷電等異常停機時,注冊中心能自動刪除提供者信息。

當注冊中心重啟時,能自動恢復注冊數(shù)據(jù),以及訂閱請求。

當會話過期時,能自動恢復注冊數(shù)據(jù),以及訂閱請求。

當設置 check="false" 時,記錄失敗注冊和訂閱請求,后臺定時重試。

可通過 username="admin" password="1234" 設置zookeeper登錄信息。

可通過 group="dubbo" 設置zookeeper的根節(jié)點,不設置將使用無根樹。

支持號通配符 group="" version="*" ,可訂閱服務的所有分組和所有版本的提供者。

源碼

zookeeper注冊中心的源碼為com.alibaba.dubbo.registry.zookeeper.ZookeeperRegistry。

ZookeeperRegistry 類繼承自 FailbackRegistry,F(xiàn)ailbackRegistry 又繼承自 AbstractRegistry,AbstractRegistry實現(xiàn)了 RegistryService 接口。

因此我們閱讀源碼順序為:RegistryService -> AbstractRegistry -> FailbackRegistry -> ZookeeperRegistry

RegistryService 接口

關于RegistryService接口RegistryService,Dubbo提供了詳細的注釋。

public interface RegistryService {
    /**
     * 注冊數(shù)據(jù),比如:提供者地址,消費者地址,路由規(guī)則,覆蓋規(guī)則,等數(shù)據(jù)。
     * 
     * 注冊需處理契約:<br>
     * 1. 當URL設置了check=false時,注冊失敗后不報錯,在后臺定時重試,否則拋出異常。<br>
     * 2. 當URL設置了dynamic=false參數(shù),則需持久存儲,否則,當注冊者出現(xiàn)斷電等情況異常退出時,需自動刪除。<br>
     * 3. 當URL設置了category=routers時,表示分類存儲,缺省類別為providers,可按分類部分通知數(shù)據(jù)。<br>
     * 4. 當注冊中心重啟,網(wǎng)絡抖動,不能丟失數(shù)據(jù),包括斷線自動刪除數(shù)據(jù)。<br>
     * 5. 允許URI相同但參數(shù)不同的URL并存,不能覆蓋。<br>
     * 
     * @param url 注冊信息,不允許為空,如:dubbo://10.20.153.10/com.alibaba.foo.BarService?version=1.0.0&application=kylin
     */
    void register(URL url);
    /**
     * 取消注冊.
     * 
     * 取消注冊需處理契約:<br>
     * 1. 如果是dynamic=false的持久存儲數(shù)據(jù),找不到注冊數(shù)據(jù),則拋IllegalStateException,否則忽略。<br>
     * 2. 按全URL匹配取消注冊。<br>
     * 
     * @param url 注冊信息,不允許為空,如:dubbo://10.20.153.10/com.alibaba.foo.BarService?version=1.0.0&application=kylin
     */
    void unregister(URL url);
    /**
     * 訂閱符合條件的已注冊數(shù)據(jù),當有注冊數(shù)據(jù)變更時自動推送.
     * 
     * 訂閱需處理契約:<br>
     * 1. 當URL設置了check=false時,訂閱失敗后不報錯,在后臺定時重試。<br>
     * 2. 當URL設置了category=routers,只通知指定分類的數(shù)據(jù),多個分類用逗號分隔,并允許星號通配,表示訂閱所有分類數(shù)據(jù)。<br>
     * 3. 允許以interface,group,version,classifier作為條件查詢,如:interface=com.alibaba.foo.BarService&version=1.0.0<br>
     * 4. 并且查詢條件允許星號通配,訂閱所有接口的所有分組的所有版本,或:interface=*&group=*&version=*&classifier=*<br>
     * 5. 當注冊中心重啟,網(wǎng)絡抖動,需自動恢復訂閱請求。<br>
     * 6. 允許URI相同但參數(shù)不同的URL并存,不能覆蓋。<br>
     * 7. 必須阻塞訂閱過程,等第一次通知完后再返回。<br>
     * 
     * @param url 訂閱條件,不允許為空,如:consumer://10.20.153.10/com.alibaba.foo.BarService?version=1.0.0&application=kylin
     * @param listener 變更事件監(jiān)聽器,不允許為空
     */
    void subscribe(URL url, NotifyListener listener);
    /**
     * 取消訂閱.
     * 
     * 取消訂閱需處理契約:<br>
     * 1. 如果沒有訂閱,直接忽略。<br>
     * 2. 按全URL匹配取消訂閱。<br>
     * 
     * @param url 訂閱條件,不允許為空,如:consumer://10.20.153.10/com.alibaba.foo.BarService?version=1.0.0&application=kylin
     * @param listener 變更事件監(jiān)聽器,不允許為空
     */
    void unsubscribe(URL url, NotifyListener listener);
    /**
     * 查詢符合條件的已注冊數(shù)據(jù),與訂閱的推模式相對應,這里為拉模式,只返回一次結(jié)果。
     * 
     * @see com.alibaba.dubbo.registry.NotifyListener#notify(List)
     * @param url 查詢條件,不允許為空,如:consumer://10.20.153.10/com.alibaba.foo.BarService?version=1.0.0&application=kylin
     * @return 已注冊信息列表,可能為空,含義同{@link com.alibaba.dubbo.registry.NotifyListener#notify(List<URL>)}的參數(shù)。
     */
    List<URL> lookup(URL url);
}

AbstractRegistry 抽象類

從構(gòu)造函數(shù)可以看出 AbstractRegistry 抽象類主要是提供了對注冊中心數(shù)據(jù)的文件緩存。

    String filename = url.getParameter(Constants.FILE_KEY, System.getProperty("user.home") + "/.dubbo/dubbo-registry-" + url.getHost() + ".cache");
        File file = null;
        if (ConfigUtils.isNotEmpty(filename)) {
            file = new File(filename);
            if(! file.exists() && file.getParentFile() != null && ! file.getParentFile().exists()){
                if(! file.getParentFile().mkdirs()){
                    throw new IllegalArgumentException("Invalid registry store file " + file + ", cause: Failed to create directory " + file.getParentFile() + "!");
                }
            }
        }

Dubbo會在用戶目錄創(chuàng)建./dubbo文件夾及緩存文件,以windows為例,生成的緩存文件為:C:\Users\你的登錄用戶名/.dubbo/dubbo-registry-127.0.0.1.cache

FailbackRegistry 抽象類

FailbackRegistry 顧名思義是主要提供的是失敗自動恢復,同樣看一下構(gòu)造函數(shù),在構(gòu)造函數(shù)中會通過 ScheduledExecutorService 一直執(zhí)行Retry方法進行重試。

    public FailbackRegistry(URL url) {
        super(url);
        int retryPeriod = url.getParameter(Constants.REGISTRY_RETRY_PERIOD_KEY, Constants.DEFAULT_REGISTRY_RETRY_PERIOD);
        this.retryFuture = retryExecutor.scheduleWithFixedDelay(new Runnable() {
            public void run() {
                try {
                    retry();
                } catch (Throwable t) { 
                    logger.error("Unexpected error occur at failed retry, cause: " + t.getMessage(), t);
                }
            }
        }, retryPeriod, retryPeriod, TimeUnit.MILLISECONDS);
    }

retry()方法主要的從各個操作中的失敗列表取出失敗的操作進行重試。

  protected void retry() {
        if (! failedRegistered.isEmpty()) {
            Set<URL> failed = new HashSet<URL>(failedRegistered);
            if (failed.size() > 0) {
                if (logger.isInfoEnabled()) {
                    logger.info("Retry register " + failed);
                }
                try {
                    for (URL url : failed) {
                        try {
                            doRegister(url);
                            failedRegistered.remove(url);
                        } catch (Throwable t) { // 忽略所有異常,等待下次重試
                            logger.warn("Failed to retry register " + failed + ", waiting for again, cause: " + t.getMessage(), t);
                        }
                    }
                } catch (Throwable t) { // 忽略所有異常,等待下次重試
                    logger.warn("Failed to retry register " + failed + ", waiting for again, cause: " + t.getMessage(), t);
                }
            }
        }
        if(! failedUnregistered.isEmpty()) {
             //......
             doUnregister(url);
             failedUnregistered.remove(url);
             //.....
        }
        if (! failedSubscribed.isEmpty()) {
             //.....
        }
        if (! failedUnsubscribed.isEmpty()) {
            //.......
        }
        if (! failedNotified.isEmpty()) {
            //.......
        }
    }

同時提供了幾個抽象方法

ZookeeperRegistry 類

ZookeeperRegistry流程

服務提供者啟動時

向/dubbo/com.foo.BarService/providers目錄下寫入自己的URL地址。

服務消費者啟動時

訂閱/dubbo/com.foo.BarService/providers目錄下的提供者URL地址。

并向/dubbo/com.foo.BarService/consumers目錄下寫入自己的URL地址。

監(jiān)控中心啟動時

訂閱/dubbo/com.foo.BarService目錄下的所有提供者和消費者URL地址。

ZookeeperRegistry 主要是實現(xiàn)了FailbackRegistry的那幾個抽象方法。本次也主要分析 doRegister(),doSubscribe()這兩個方法。

doRegister()

    protected void doRegister(URL url) {
        try {
        	zkClient.create(toUrlPath(url), url.getParameter(Constants.DYNAMIC_KEY, true));
        } catch (Throwable e) {
            throw new RpcException("Failed to register " + url + " to zookeeper " + getUrl() + ", cause: " + e.getMessage(), e);
        }
    }
    public void create(String path, boolean ephemeral) {
		int i = path.lastIndexOf('/');
		if (i > 0) {
			create(path.substring(0, i), false);
		}
		if (ephemeral) {
			createEphemeral(path);
		} else {
			createPersistent(path);
		}
	}
}

doRegister() 主要是調(diào)用zkClient創(chuàng)建一個節(jié)點。 create()以遞歸的方式創(chuàng)建節(jié)點,通過判斷Url中dynamic=false 判斷創(chuàng)建的是持久化節(jié)點還是臨時節(jié)點。

創(chuàng)建的結(jié)果為:

doSubscribe()

doSubscribe() 訂閱Zookeeper節(jié)點是通過創(chuàng)建ChildListener來實現(xiàn)的具體調(diào)用的方法是 addChildListener()

addChildListener()又調(diào)用 AbstractZookeeperClient.addTargetChildListener()然后調(diào)用subscribeChildChanges()

最后調(diào)用ZkclientZookeeperClient ZkClientd.watchForChilds()

    protected void doSubscribe(final URL url, final NotifyListener listener) {
        //....
        List<String> children = zkClient.addChildListener(path, zkListener);
        //.....
    }
    public List<String> addChildListener(String path, final ChildListener listener) {
        //......
		return addTargetChildListener(path, targetListener);
    }
    ```java
	public List<String> addTargetChildListener(String path, final IZkChildListener listener) {
		return client.subscribeChildChanges(path, listener);
	}
    public List<String> subscribeChildChanges(String path, IZkChildListener listener) {
        //.....
        return watchForChilds(path);
    }

以上就是動力節(jié)點小編介紹的"Dubbo注冊中心分析",希望對大家有幫助,想了解更多可查看Dubbo教程。動力節(jié)點在線學習教程,針對沒有任何Java基礎的讀者學習,讓你從入門到精通,主要介紹了一些Java基礎的核心知識,讓同學們更好更方便的學習和了解Java編程,感興趣的同學可以關注一下。

提交申請后,顧問老師會電話與您溝通安排學習

免費課程推薦 >>
技術文檔推薦 >>
主站蜘蛛池模板: 成人影院高清在线观看免费网站 | 成人不卡视频 | 午夜精品在线免费观看 | 久久天天躁日日躁狠狠躁 | 伊人成人在线视频 | 欧美亚洲欧美区 | 亚洲国产成人久久午夜 | 欧美国产成人精品一区二区三区 | 日本ccc三级 | 欧美亚洲综合在线观看 | 小明永久免费视频 | 免费污视频在线 | 一个人看的www免费视频中文 | v天堂中文在线 | 在线观看日韩 | 免费大片在线观看www | 亚洲日本1区2区3区二区 | 老司机免费福利午夜入口ae58 | 国产在线观看免费视频软件 | 成年人精品视频 | aⅴ一区二区三区无卡无码 aⅴ在线免费观看 | 一卡二卡3卡四卡网站精品国 | 一级做a爰片久久毛片免费看 | 美国黄色毛片一级 | 97精品视频在线观看 | 久久伊人婷婷 | 欧美一区日韩精品 | 国产成人在线播放视频 | 亚洲视频高清 | 人与鲁牲交持级毛片 | 三级全黄的全黄三级三级播放 | 国产在线观看成人 | 国产午夜在线观看视频播放 | 一级一片免费播放 | 日日干夜夜骑 | 亚洲欧洲色天使日韩精品 | 黄网站免费观看 | 麻豆精品传媒一二三区在线视频 | 韩国xxxx色视频在线观看 | 最新男同志freevideos | 国产伦精品一区二区三区免费 |