目標:介紹接下來集羣分哪幾部分來描述,介紹dubbo在集羣中涉及到的幾個功能,介紹dubbo-cluster下跟各個功能相關的接口
若是說分佈式是爸爸住在杭州,媽媽住在上海,那麼集羣就是兩個爸爸,一個住在杭州,一個住在上海。對於分佈式和集羣有高吞吐量、高可用的目標。對於分佈式來講每一個服務器部署的服務任務是不一樣的,可能須要這些服務器上的服務共同協做才能完成整個業務流程,各個服務各司其職。而集羣不同,集羣是同一個服務,被部署在了多個服務器上,每一個服務器的任務都是同樣的,是爲了減小壓力集中的問題,而集羣中就會出現負載均衡、容錯等問題。java
dubbo的集羣涉及到如下幾部份內容:git
以上幾部分跟《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——集羣模塊「中的圖片。下面咱們直接對應各個部分來介紹相應的接口源碼。數組
關於目錄介紹請查看《dubbo源碼解析(一)Hello,Dubbo》的"(二)dubbo-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表明了一個集羣實現。似懂非懂就夠了,後面看具體的實現會比較清晰。網絡
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上應用規則。負載均衡
@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
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。定義的兩個方法也比較好理解。
@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也提供了四種負載均衡策略,也會在下面文章講解。
@SPI public interface Merger<T> { /** * 合併T數組,返回合併後的T對象 * @param items * @return */ T merge(T... items); }
該接口是分組聚合,將某對象數組合併爲一個對象。
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集合。
@SPI public interface RouterFactory { /** * Create router. * 建立路由 * @param url * @return router */ @Adaptive("protocol") Router getRouter(URL url); }
該接口是路由工廠接口,定義了得到路由實例的方法。
該部分相關的源碼解析地址: https://github.com/CrazyHZM/i...
該文章大體講解了dubbo中集羣模塊的內容,而且講解了相關接口的設計。接下來我將開始對cluster集羣模塊中的集羣容錯部分,也就是support中的源碼進行講解。