dubbo中registry、route、directory、cluster、loadbalance、route的关系以及一个引用操作和调用操作到底干了啥

zk是比较典型场景,所以注册中心都是以zk作为例子的

1 对于registry,提供者没有这个,消费者才有。为什么?
因为只有消费者才需要去注册中心拿到provide的信息,而provider是不需要关注的,provider只需要去注册就好。在RegistryProtocol的export方法中,可以看到在registry方法里面直接在注册中心写信息就够了。

2 RegistryDirectory是啥意思?如果有三个zk,有几个directory?几个registry?
一个目录其实就是很容易想到就是一个dubbo提供者的interfacename在zk上面的/duboo+interfacename的目录,但不仅仅是这样,如果有多个zk,那么有三个目录,因为这三个目录在不同的zk上面。

一个消费者在初始化得到引用的时候,在loadRegistries里面,如果url里面有多个以分号隔开的注册中心的ip+port,那么就得到多个注册中心的url,那么每个url都需要经过registryProcol处理,具体来说createProxy里面就是要对每个注册url进行refer操作

所以directory的构造函数里面有两个东西来限定唯一性:注册中心url和provider的interfacename。对于一个消费者,假设只有一个provider的interfacename需要引用的话,在三个zk的前提下,那么要维护三个registry,三个registry都各自有自己的directory。消费者初始化引用的时候每个directory和对应的registry都需要一个方面跟提供者一样,去不同的zk上面的consumer写入自己的信息,另外要分别订阅这个interfaceface路径下的provider、configure、route信息。第一次订阅的时候,顺便把provider的具体信息都存在directory的methodInvokerMap中,以后要调用的时候就从这里取。

3 dubbo里面经常说的FailoverClusterinvoer、BroadcastClusterInvoker等等这些Cluster是啥意思?

首先cluster接口只有一个方法,就是通过join得到一个invoker,不要被名字误导了,虽然叫cluster,其实没有保存多个invoker,并不是保存了一个集合。虽然叫join,但是其实是利用spi根据配置得到不同的cluster,可以理解成:cluster的join就是根据配置得到不同ClusterInvoker实现。当然还有一个MockClusterWrapper,所以所有的Cluster其实都被这个Wrapper都包了一层,这个是dubbo的spi注入做的,看名字就知道加这一层是为了提前拦截,方便mock测试用的。

4 Cluster和loadbalance的关系

不同的Cluster的实现里面都有一个doInvoke方法,dubbo提供者被调用的时候都会走这个方法,因为cluster本质也是一个invoker,不同的Cluster具有不同的doInvoke实现,在遇到多个invoker调用不顺利情况下 做不同处理。
而loadbalance不同,他是用来挑选优先使用哪个invoker的,一般有随机、一致性哈希,这个也是spi来挑选的。在cluster的共同的父类实现中,也就是在doinvoke之前,都会调用一次loadbalance的select来选出优先的invoker

5 dubbo与zk的关系咋样的,dubbo怎么被zk通知的?

我们说过provider是不需要监听的,消费者才要。我感觉dubbo的zklistener太绕了,dubbox稍微好点。消费者在两个地方进行监听:与zk连接的statechanged回调以及自己引用的interface目录的provider、configure、route目录发生变化的时候,也会有childchanged的回调。
statechanged回调的注册应该比较好找,就是zkclient去连接zk的时候,建立的回调注册。这个里的回调处理是,一旦发现重连,那么把已经注册的、已经订阅的全部划分到failed的list里面,zkregistry有一个心跳,定期检查这些failed的list里面是不是有数据,如果有那么重新注册、订阅。
childchanged是在订阅的时候注册的,也就是doSubscribe里面。当provider、configure、route发生变化的时候,最终调用到RegistryDirectory的notify方法,回调的传过来的参数是当前这个目录比如provider目录下面的实际子节点的全部信息。以provider目录为例子,拿到这些重要信息以后,RegistryDirectory就会根据新的provider的url-list,做一次refreshInvoker,做之前还把缓存的文件也根据这个更新的。

所以说consumer就是通过这个回调感知provider的变化的,看得出来如果zk回调出问题,dubbo就找不到提供者,并且缓存文件也坏了。并且dubbo没有主动去轮训检查zk的当前信息,这块还是比较脆弱的。
我看dubbo官网说的是,阿里内部没用zk,而是用自己的数据库作为注册中心。

6 refreshInvoker 里面做了啥?
前面只是讲到得到了一个provider的url、list,并没有得到一个provider的实体,其实有了provider,需要使用dubboProcol的refer去真正引用一个service,与service建立长链接关系。底层建立transport层的通信关系,我是使用netty4看的有时间可以写写。
至于序列化那块,默认用的hessian,比较繁琐。dubbo没有用protobuf,如果用的话,性能更好,并且代码应该也不需要写这么多。所以没有细研究了

7 消费者refer得到的到底是啥?
根据前面提到的,我们可以简单总结下,假如有三个zk,那么dorefer干下面几个事情:
创建三个registry、三个directory。
与三个registry建立长链接,创建consumer目录上自己的信息,这个叫注册。
然后订阅provider的信息,并且把provider的url信息拿到后refreshInvoker
与这些dubbo-invoker建立连接关系

8 那么问题来了,refer方法结果是dubbo-invoker吗?如果是的话 就用不到cluster、loadbalance这些了。
在doRefer方法的最后,还是调用了cluster.join(directory)得到invoke返回回去。也就是最终返回了三个MockClusterWrapper,里面是FailoverClusterInvoker(默认spi)
对于directory或者说registry做了一次cluster.join,这是因为一个directory可能相同的版本的provider都不止一个,所以不同的provider是一个cluster,这里面存在一个选择。

刚刚外面说了返回了三个MockClusterWrapper,但是consumer或者说我们的业务使用者来说,不应该感知这些,所以对于三个注册中心的三个MockClusterWrapper还要做一次cluster.join:
URL u = registryURL.addParameter(Constants.CLUSTER_KEY, AvailableCluster.NAME);
invoker = cluster.join(new StaticDirectory(u, invokers));
这次是指定用了AvailableCluster,于是又返回了一个MockClusterInvoker,里面包裹了真正的AvailableCluster,这个AvailableCluster的doInvoke方法就是遍历自己的invoke-list,只要可用就用这个,也就是说三个zk,只要有一个没问题,就直接用这个zk的url代表的provider
当然这个ref还要做一次proxy动态代理才能真正返回给用户使用

9 Route是干啥用的,在哪里生效的?
在执行真正的invoke时候,为了使用cluster、loadbalance,必须经过clusterinvoke,在虚基类AbstractClusterInvoker的doInvoke方法中,首先是利用directory.list针对这个invocation做一次筛选,
List<Invoker<T>> invokers = doList(invocation);可以不用考虑,就是根据调用方法拿到invokers(这里的invokers都是通过refreshinvokers拿到的),对于StaticDirectory直接返回所有invokers。
然后会用默认的MockInvokersSelector做一次route筛选处理,通过名字知道还是为了mock调试用的。其他的route还有ConditionRouter和ScriptRouter,路由规则决定一次 dubbo 服务调用的目标服务器。dubbo官网目前是试用阶段。

10 一次调用进行了两次cluster的选择
一次调用,首先选择任一一个可用registry或者说directory的invoker,也就是确定用这个注册中心。后面还要选择到底用这个注册中心的哪个provider,默认spi是FailoverClusterinvoer,然后走loadbalance、cluster逻辑选出真正的invoker,走dubbo调用流程

原文地址:https://www.cnblogs.com/notlate/p/10088829.html

时间: 2024-10-14 17:27:31

dubbo中registry、route、directory、cluster、loadbalance、route的关系以及一个引用操作和调用操作到底干了啥的相关文章

Dubbo中集群Cluster,负载均衡,容错,路由解析

Dubbo中的Cluster可以将多个服务提供方伪装成一个提供方,具体也就是将Directory中的多个Invoker伪装成一个Invoker,在伪装的过程中包含了容错的处理,负载均衡的处理和路由的处理.这篇文章介绍下集群相关的东西,开始先对着文档解释下容错模式,负载均衡,路由等概念,然后解析下源码的处理.(稍微有点乱,心情不太好,不适合分析源码.) 集群的容错模式 Failover Cluster 这是dubbo中默认的集群容错模式 失败自动切换,当出现失败,重试其它服务器. 通常用于读操作,

Dubbo中Directory解析

Directory代表多个Invoker,可以把它看成List Directory接口 Directory接口继承了Node接口: 1234567 public interface Directory<T> extends Node { //获取服务类型 Class<T> getInterface(); //invoker列表,服务的列表 List<Invoker<T>> list(Invocation invocation) throws RpcExcep

Dubbo中订阅和通知解析

Dubbo中关于服务的订阅和通知主要发生在服务提供方暴露服务的过程和服务消费方初始化时候引用服务的过程中. 服务引用过程中的订阅和通知 在服务消费者初始化的过程中,会有一步是进行服务的引用,具体的代码是在RegistryProtocol的refer方法: 12345678910111213141516171819 public <T> Invoker<T> refer(Class<T> type, URL url) throws RpcException { url =

Dubbo中服务消费者和服务提供者之间的请求和响应过程

服务提供者初始化完成之后,对外暴露Exporter.服务消费者初始化完成之后,得到的是Proxy代理,方法调用的时候就是调用代理. 服务消费者经过初始化之后,得到的是一个动态代理类,InvokerInvocationHandler,包含MockClusterInvoker,MockClusterInvoker包含一个RegistryDirectory和FailoverClusterInvoker. Java动态代理,每一个动态代理类都必须要实现InvocationHandler这个接口,并且每一

Dubbo中暴露服务的过程解析

dubbo暴露服务有两种情况,一种是设置了延迟暴露(比如delay="5000"),另外一种是没有设置延迟暴露或者延迟设置为-1(delay="-1"): 设置了延迟暴露,dubbo在Spring实例化bean(initializeBean)的时候会对实现了InitializingBean的类进行回调,回调方法是afterPropertySet(),如果设置了延迟暴露,dubbo在这个方法中进行服务的发布. 没有设置延迟或者延迟为-1,dubbo会在Spring实例

Dubbo中SPI扩展机制解析

dubbo的SPI机制类似与Java的SPI,Java的SPI会一次性的实例化所有扩展点的实现,有点显得浪费资源. dubbo的扩展机制可以方便的获取某一个想要的扩展实现,每个实现都有自己的name,可以通过name找到具体的实现. 每个扩展点都有一个@Adaptive实例,用来注入到依赖这个扩展点的某些类中,运行时通过url参数去动态判断最终选择哪个Extension实例用. dubbo的SPI扩展机制增加了对扩展点自动装配(类似IOC)和自动包装(类似AOP)的支持. 标注了@Activat

Dubbo中对Spring配置标签扩展

Spring提供了可扩展Schema的支持,完成一个自定义配置一般需要以下步骤: 设计配置属性和JavaBean 编写XSD文件 编写NamespaceHandler和BeanDefinitionParser完成解析工作 编写spring.handlers和spring.schemas串联起所有部件 在Bean文件中应用 dubbo中所有dubbo的标签,都统一用DubboBeanDefinitionParser进行解析,基于一对一属性映射,将XML标签解析为Bean对象. 下面我们就用dubb

Zookeeper笔记(七)Zookeeper在Dubbo中的应用

Zookeeper在Dubbo中的应用 Dubbo的架构 节点角色说明: Provider: 暴露服务的服务提供方.Consumer: 调用远程服务的服务消费方.Registry: 服务注册与发现的注册中心.Monitor: 统计服务的调用次调和调用时间的监控中心.Container: 服务运行容器.调用关系说明: 0. 服务容器负责启动,加载,运行服务提供者.1. 服务提供者在启动时,向注册中心注册自己提供的服务.2. 服务消费者在启动时,向注册中心订阅自己所需的服务.3. 注册中心返回服务提

服务化改造实践 | 如何在 Dubbo 中支持 REST

什么是 RESTREST 是 Roy Thomas Fielding [1] 在 2000 年他的博士论文 [2] "架构风格以及基于网络的软件架构设计" 中提出来的一个概念.REST 是 RESTransfer 的缩写,翻译过来就是 "表现层状态转化".REST 就是 Roy 在这篇论文中提出的面向互联网的软件所应当具备的架构风格. 按照 REpresentational State Transfer 的字面意思,可以把应用看成是一个虚拟的状态机,软件提供的不是服