目标:介绍接下来集群分哪几部分来描述,介绍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中的源码进行讲解。