dubbo源码:dubbo服务端与消费端交互过程

概要

在这里插入图片描述

服务端启动过程

  • Step 1:生成注册中心Registry URL集合

    对dubbo的registries属性进行校验(<dubbo:registry标签或properties文件中读取dubbo.registry.address属性),并获取注册中心的地址,生成Registry URL集合

  • Step 2:根据配置参数构造URL(如dubbo版本号、端口号等等)

  • Step 3:服务暴露

    1. 本地服务暴露过程

      • 构造 injvm URL
      • 默认Javassist动态代理根据接口、代理和URL生成AbstractProxyInvoker匿名实例
      • InjvmProtocol通过export方法构造出InjvmExporter
      • 将InjvmExporter对象存入ServiceConfig对象的exporters属性中,本地服务暴露完成
    2. 远程服务暴露过程

      • 获取monitor标签的监控地址信息,并作为monitor参数放入服务提供者的URL中

      • 将服务提供者的URL地址作为export参数的值放入注册地址URL中

      • 默认Javassist动态代理根据接口、代理和注册地址URL生成AbstractProxyInvoker匿名实例

      • RegistryProtocol通过export方法重新构造出Exporter对象,过程如下:

        • 将上一步创建的Invoker封装成RegistryProtocol静态内部类InvokerDelegete

        • 调用DubboProtocol的export方法,并返回DubboExporter

          • 构造DubboExporter
          • 开启ExchangeServer服务
        • 根据DubboExporter等信息重新构造出ExporterChangeableWrapper

        • 获取注册中心,并注册服务

        • 获取订阅URL,构建订阅回调notify,并向注册中心订阅URL,同时注册回调监听器

        • 重新构造Exporter对象

      • 将RegistryProtocol通过export方法构造出的Exporter对象存入ServiceConfig对象的exporters属性中,服务暴露完成

消费端启动过程

  • Step 1:获取配置参数放到map中

  • Step 2:引用服务

    1. 引用本地服务

      • 构造InjvmInvoker
      • ProtocolListenerWrapper中封装成ListenerInvokerWrapper对象返回,在ListenerInvokerWrapper内部遍历所有监听器并执行其refered方法
      • 在ProtocolFilterWrapper类中对返回的Invoker对象构建filter链
    2. 引用远程服务(调用RegistryProtocol的refer方法引用远程服务)

      • 获取注册中心(若已经创建则直接返回,否则创建)

        • 启动文件保存定时器(如生成dubbo-registry-127.0.0.1.cache)
        • loadProperties()把上⾯面创建的缓存⽂文件读进内存中
        • 获取该注册中⼼的所有的订阅者,并通知到每个订阅者下的所有监听者(listener)
        • FailbackRegistry再开启一个线程来启动失败重试定时器,retryPeriod默认值是5s
      • 获取分组(group)信息

      • 构造consumer订阅URL,并注册到注册中心上,同时通知每个订阅者下的所有监听者(listener)

      • 创建RegistryDirectory,并作为Listener放到订阅该consumer URL的Listener集合中并发送订阅请求

      • 获取服务端提供者providers URL列表,并根据invokerURL列表转换为invoker列表,最后将invokers列表转成与方法的映射关系(缓存到RegistryDirectory中methodInvokerMap属性中)

        转换规则如下:

        1. 如果url已经被转换为invoker,则不在重新引用,直接从缓存中获取,注意如果url中任何一个参数变更也会重新引用
        2. 如果传入的invoker列表不为空,则表示最新的invoker列表
        3. 如果传入的invokerUrl列表是空,则表示只是下发的override规则或route规则,需要重新交叉对比,决定是否需要重新引用
      • 根据RegistryDirectory生成MockClusterInvoker并返回

  • Step 3:创建代理

    调用JavassistProxyFactory的getProxy方法来创建代理,并放ReferenceConfig类接口代理类引用ref中(默认使用Javassist代理)

消费端调用过程

  • Step 1:cluster层调用

    调用MockClusterInvoker的invoke方法,最终调用AbstractClusterInvoker的invoke方法,调用过程如下:

    1. 检查RPC Cluster invoker中要执行的接口是否被销毁,若销毁,则抛出异常

    2. 在调用提供者之前,会获取当前线程临时变量里的RpcContext对象,再将RpcContext对象里的参数设置到Invocation对象

    3. 列出所有的Invoker,即从RegistryDirectory中的methodInvokerMap属性中取出所有的Invoker

      在消费端启动过程中已经方法和对应的invoker关系存放到了RegistryDirectory中的methodInvokerMap属性中

    4. 获取方法上配置的负载均衡策略,若没有配置,选择默认的策略

    5. 进入到Step 2进行protocol层调用

  • Step 2:protocol层调用

    Protocol层作用:封装RPC调用,以Invocation和Result为中心,扩展接口为Protocol、Invoker和Exporter。Protocol是服务域,它是Invoker暴露和引用的主功能入口,它负责Invoker的生命周期管理。Invoker是实体域,它是Dubbo的核心模型,其它模型都向它靠扰,或转换成它,它代表一个可执行体,可向它发起invoke调用,它有可能是一个本地的实现,也可能是一个远程的实现,也可能一个集群实现。

    以下是protocol层的调用次序

    1. ConsumerContextFilter的invoke 方法
    2. FutureFilter的invoke方法
    3. MonitorFilter中的invoke方法
    4. DubboInvoker中invoke方法(最终会调用到目标方法)
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

bboyzqh

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值