dubbo源碼解析(三十四)集羣——開篇

集羣——開篇

目標:介紹接下來集羣分哪幾部分來描述,介紹dubbo在集羣中涉及到的幾個功能,介紹dubbo-cluster下跟各個功能相關的接口

集羣是什麼?

若是說分佈式是爸爸住在杭州,媽媽住在上海,那麼集羣就是兩個爸爸,一個住在杭州,一個住在上海。對於分佈式和集羣有高吞吐量、高可用的目標。對於分佈式來講每一個服務器部署的服務任務是不一樣的,可能須要這些服務器上的服務共同協做才能完成整個業務流程,各個服務各司其職。而集羣不同,集羣是同一個服務,被部署在了多個服務器上,每一個服務器的任務都是同樣的,是爲了減小壓力集中的問題,而集羣中就會出現負載均衡、容錯等問題。java

dubbo的集羣涉及到如下幾部份內容:git

  1. 目錄:Directory能夠當作是多個Invoker的集合,可是它的值會隨着註冊中心中服務變化推送而動態變化,那麼Invoker以及如何動態變化就是一個重點內容。
  2. 集羣容錯:Cluster 將 Directory 中的多個 Invoker 假裝成一個 Invoker,對上層透明,假裝過程包含了容錯邏輯,調用失敗後,重試另外一個。
  3. 路由:dubbo路由規則,路由規則決定了一次dubbo服務調用的目標服務器,路由規則分兩種:條件路由規則和腳本路由規則,而且支持可拓展。
  4. 負載均衡策略:dubbo支持的全部負載均衡策略算法。
  5. 配置:根據url上的配置規則生成配置信息
  6. 分組聚合:合併返回結果。
  7. 本地假裝:mork一般用於服務降級,mock只在出現非業務異常(好比超時,網絡異常等)時執行

以上幾部分跟《dubbo源碼解析(一)Hello,Dubbo》的"(二)dubbo-cluster——集羣模塊「介紹有些相似,這裏再從新講一遍是爲了明確我接下來介紹集羣模塊的文章內容分佈,也就是除了本文以外,我會用七篇文章來說解以上的七部分,無論內容多少,只是爲了把相應內容區分開來,能讓讀者有選擇性的閱讀。github

在官方網站上有一段介紹我以爲寫的很是的好:算法

集羣工做過程可分爲兩個階段,第一個階段是在服務消費者初始化期間,集羣 Cluster 實現類爲服務消費者建立 Cluster Invoker 實例,即上圖中的 merge 操做。第二個階段是在服務消費者進行遠程調用時。以 FailoverClusterInvoker 爲例,該類型 Cluster Invoker 首先會調用 Directory 的 list 方法列舉 Invoker 列表(可將 Invoker 簡單理解爲服務提供者)。Directory 的用途是保存 Invoker,可簡單類比爲 List<invoker>。其實現類 RegistryDirectory 是一個動態服務目錄,可感知註冊中心配置的變化,它所持有的 Inovker 列表會隨着註冊中心內容的變化而變化。每次變化後,RegistryDirectory 會動態增刪 Inovker,並調用 Router 的 route 方法進行路由,過濾掉不符合路由規則的 Invoker。當 FailoverClusterInvoker 拿到 Directory 返回的 Invoker 列表後,它會經過 LoadBalance 從 Invoker 列表中選擇一個 Inovker。最後 FailoverClusterInvoker 會將參數傳給 LoadBalance 選擇出的 Invoker 實例的 invoker 方法,進行真正的遠程調用。segmentfault

本文要來說的無非就是這幾部份內容的一個大概,而且介紹一下這幾部份內容涉及到的接口。集羣的包結構我就不在這裏展現了,就是《dubbo源碼解析(一)Hello,Dubbo》的"(二)dubbo-cluster——集羣模塊「中的圖片。下面咱們直接對應各個部分來介紹相應的接口源碼。數組

目錄

cluster

關於目錄介紹請查看《dubbo源碼解析(一)Hello,Dubbo》的"(二)dubbo-cluster——集羣模塊「介紹。服務器

源碼分析

(一)Cluster

@SPI(FailoverCluster.NAME)
public interface Cluster {

    /**
     * Merge the directory invokers to a virtual invoker.
     * 將目錄調用程序合併到虛擬調用程序。
     * @param <T>
     * @param directory
     * @return cluster invoker
     * @throws RpcException
     */
    @Adaptive
    <T> Invoker<T> join(Directory<T> directory) throws RpcException;

}

該接口是集羣容錯接口,能夠看到它是一個可擴展接口,默認實現FailoverCluster,固然它還會有其餘的實現,每一種實現都表明了一種集羣容錯的方式,具體有哪些,能夠看下面文章的介紹,他們都在support包下面,在本文只是讓讀者知道接口的定義。那麼它還定義了一個join方法,做用就是把Directory對象變成一個 Invoker 對象用來後續的一系列調用。該Invoker表明了一個集羣實現。似懂非懂就夠了,後面看具體的實現會比較清晰。網絡

(二)Configurator

public interface Configurator extends Comparable<Configurator> {

    /**
     * get the configurator url.
     * 配置規則,生成url
     * @return configurator url.
     */
    URL getUrl();

    /**
     * Configure the provider url.
     * 把規則配置到URL中
     *
     * @param url - old rovider url.
     * @return new provider url.
     */
    URL configure(URL url);

}

該接口是配置規則的接口,定義了兩個方法,第一個是配置規則,而且生成url,第二個是把配置配置到舊的url中,其實都是在url上應用規則。負載均衡

(三)ConfiguratorFactory

@SPI
public interface ConfiguratorFactory {

    /**
     * get the configurator instance.
     * 得到configurator實例
     * @param url - configurator url.
     * @return configurator instance.
     */
    @Adaptive("protocol")
    Configurator getConfigurator(URL url);

}

該接口是Configurator的工廠接口,定義了一個getConfigurator方法來得到Configurator實例,比較好理解。dom

(四)Directory

public interface Directory<T> extends Node {

    /**
     * get service type.
     * 得到服務類型
     * @return service type.
     */
    Class<T> getInterface();

    /**
     * list invokers.
     * 得到全部服務Invoker集合
     * @return invokers
     */
    List<Invoker<T>> list(Invocation invocation) throws RpcException;

}

該接口是目錄接口,Directory 表明了多個 Invoker,而且它的值會隨着註冊中心的服務變動推送而變化 。一個服務類型對應一個Directory。定義的兩個方法也比較好理解。

(五)LoadBalance

@SPI(RandomLoadBalance.NAME)
public interface LoadBalance {

    /**
     * select one invoker in list.
     * 選擇一個合適的調用,而且返回
     * @param invokers   invokers.
     * @param url        refer url
     * @param invocation invocation.
     * @return selected invoker.
     */
    @Adaptive("loadbalance")
    <T> Invoker<T> select(List<Invoker<T>> invokers, URL url, Invocation invocation) throws RpcException;

}

該接口是負載均衡的接口,dubbo也提供了四種負載均衡策略,也會在下面文章講解。

(六)Merger

@SPI
public interface Merger<T> {

    /**
     * 合併T數組,返回合併後的T對象
     * @param items
     * @return
     */
    T merge(T... items);

}

該接口是分組聚合,將某對象數組合併爲一個對象。

(七)Router

public interface Router extends Comparable<Router> {

    /**
     * get the router url.
     * 得到路由規則的url
     * @return url
     */
    URL getUrl();

    /**
     * route.
     * 篩選出跟規則匹配的Invoker集合
     * @param invokers
     * @param url        refer url
     * @param invocation
     * @return routed invokers
     * @throws RpcException
     */
    <T> List<Invoker<T>> route(List<Invoker<T>> invokers, URL url, Invocation invocation) throws RpcException;

}

該接口是路由規則的接口,定義的兩個方法,第一個方法是得到路由規則的url,第二個方法是篩選出跟規則匹配的Invoker集合。

(八)RouterFactory

@SPI
public interface RouterFactory {

    /**
     * Create router.
     * 建立路由
     * @param url
     * @return router
     */
    @Adaptive("protocol")
    Router getRouter(URL url);

}

該接口是路由工廠接口,定義了得到路由實例的方法。

後記

該部分相關的源碼解析地址: https://github.com/CrazyHZM/i...

該文章大體講解了dubbo中集羣模塊的內容,而且講解了相關接口的設計。接下來我將開始對cluster集羣模塊中的集羣容錯部分,也就是support中的源碼進行講解。

相關文章
相關標籤/搜索