架构

image.png

服务暴露全流程

我们在深入源码之前来看下总的流程,有个大致的印象看起来比较不容易晕
代码的流程来看大致可以分为三个步骤(本文默认都需要暴露服务到注册中心)。
第一步是检测配置,如果有些配置空的话会默认创建,并且组装成 URL 。
第二步是暴露服务,包括暴露到本地的服务和远程的服务。
第三步是注册服务至注册中心。
dubbo 流程图 - 图2
对象构建转换的角度看可以分为两个步骤。
第一步是将服务实现类转成 Invoker。
第二部是将 Invoker 通过具体的协议转换成 Exporter。
dubbo 流程图 - 图3

服务引用大致流程

我们已经得知 Provider 将自己的服务暴露出来,注册到注册中心,而 Consumer 无非就是通过一波操作从注册中心得知 Provider 的信息,然后自己封装一个调用类和 Provider 进行深入地交流。
而之前的文章我都已经提到在 Dubbo 中一个可执行体就是 Invoker,所有调用都要向 Invoker 靠拢,因此可以推断出应该要先生成一个 Invoker,然后又因为框架需要往不侵入业务代码的方向发展,那我们的 Consumer 需要无感知的调用远程接口,因此需要搞个代理类,包装一下屏蔽底层的细节。
整体大致流程如下:
dubbo 流程图 - 图4

服务引入的三种方式

服务的引入又分为了三种,第一种是本地引入、第二种是直接连接引入远程服务、第三种是通过注册中心引入远程服务。
dubbo 流程图 - 图5

详细的调用流程

dubbo 流程图 - 图6

调用的三种方式

从上面的代码可以看到调用一共分为三种,分别是 oneway、异步、同步。
oneway 还是很常见的,就是当你不关心你的请求是否发送成功的情况下,就用 oneway 的方式发送,这种方式消耗最小,啥都不用记,啥都不用管。
异步调用,其实 Dubbo 天然就是异步的,可以看到 client 发送请求之后会得到一个 ResponseFuture,然后把 future 包装一下塞到上下文中,这样用户就可以从上下文中拿到这个 future,然后用户可以做了一波操作之后再调用 future.get 等待结果。
同步调用,这是我们最常用的,也就是 Dubbo 框架帮助我们异步转同步了,从代码可以看到在 Dubbo 源码中就调用了 future.get,所以给用户的感觉就是我调用了这个接口的方法之后就阻塞住了,必须要等待结果到了之后才能返回,所以就是同步的。
可以看到 Dubbo 本质上就是异步的,为什么有同步就是因为框架帮我们转了一下,而同步和异步的区别其实就是 future.get 在用户代码被调用还是在框架代码被调用

集群容错负载均衡


所以说 RegistryDirectory 一共有三大作用:

  1. 获取 invoker 列表
  2. 监听注册中心的变化
  3. 刷新 invokers。


Dubbo 默认的 cluster 实现有很多,主要有以下几种:
dubbo 流程图 - 图7