前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >[dubbo 源码之 ]2. 服务消费方如何启动服务

[dubbo 源码之 ]2. 服务消费方如何启动服务

作者头像
Isaac Zhang
发布2020-03-19 15:03:39
4890
发布2020-03-19 15:03:39
举报
文章被收录于专栏:奔跑的人生奔跑的人生
启动流程

消费者在启动之后,会通过ReferenceConfig#get()来生成远程调用代理类。在get方法中,会启动一系列调用函数,我们来一个个解析。

配置同样包含2种:

  • XML
  • Java API
1. new ReferenceConfig

在此阶段,会初始化org.apache.dubbo.config.AbstractConfig & org.apache.dubbo.config.ReferenceConfig的静态变量以及静态代码块。

2. ReferenceConfig#get
  • ReferenceConfig#init
    1. 通过DubboBootstrap启动dubbo。
    2. 继而初始化服务的元数据信息,URL.buildKey(interfaceName, group, version)这段用来生成唯一服务的key,所以我们之前说dubbo的唯一标识是通过全路径和group以及version来决定的。
    3. 接下来通过org.apache.dubbo.config.utils.ConfigValidationUtils#checkMock来检查我们mock是否设置正确。
    4. 设置一系列要用的参数(系统运行参数、是否为consumer、是否为泛型调用等等),检查dubbo的注册地址,默认为当前主机IP
  • ReferenceConfig#createProxy 创建调用代理开始
  1. ReferenceConfig#shouldJvmRefer首先判断是否为Injvm调用
  2. 如果不为injvm,判断是否为peer to peer端对端设置,如果为p2p,那么就直连url
  3. 检查注册中心是否存在(注册中心有可能有多个)
  4. 循环检查注册中心是否有效
  5. 配置转换URL
  1. 如果只有一个注册中心,执行REF_PROTOCOL.refer(interfaceClass, urls.get(0));来将URL转为Invoker对象,因为private static final Protocol REF_PROTOCOL = ExtensionLoader.getExtensionLoader(Protocol.class).getAdaptiveExtension();是扩展是Adaptive,因此在这里会执行Protocol$Adaptive#refer方法,又由于protocol参数值为registry,因此会只是RegistryProtocol#refer,又由于被Wrapper类装配,因此会先执行三个Wrapper类,最后才能执行到RegistryProtocol#refer -> RegistryProtocol#doRefer,在doRefer方法中会订阅服务提供者地址,最后返回Invoker对象。!

那么究竟是如何生成的Invoker对象呢?我们来看下具体代码:

上述代码中,步骤1根据URL生成了一个RegistryDirectory(关于Directory接口的作用,可以自行查询一些,直白一些就是将一堆Invoker对象封装成一个List,只有2种实现RegistryDirectory & StaticDirectory,从命名可看出一个是动态可变,一个不可变),代码2 封装了订阅所要使用的参数信息,代码3则是封装绑定路由规则链,代码4订阅。代码5调用 Cluster$Adaptive#join方法生成Invoker对象。

在代码2种从zk获取服务提供者信息:

一旦zk返回服务提供者列表之后,就会调用RegistryDirectory#notify,如下:

org.apache.dubbo.common.utils.UrlUtils#isMatch中对provider和consumer的api进行匹配校验。继续跟踪:RegistryDirectory#notify -> RegistryDirectory#refreshOverrideAndInvoker -> RegistryDirectory#refreshInvoker -> RegistryDirectory#toInvokerstoInvokers正式将URL转换为Invoker,通过invoker = new InvokerDelegate<>(protocol.refer(serviceType, url), url, providerUrl); 在这里protocol#refer同样执行顺序如:

(dubbo 2.7.5) protocol#refer -> protocol$Adaptive#refer -> QosProtocolWrapper#refer -> ProtocolListenerWrapper#refer -> ProtocolFilterWrapper#refer ->AbstractProtocol#refer->DubboProtocol#protocolBindingRefer,调用代码如下:

关注getClients,其中执行了DubboProtocol#getSharedClient -> DubboProtocol#initClient 创建netty client进行连接。

因为这里使用的是明确的DubboInvoker,在回调的时候,Wrapper会对该Invoker进行包装,执行效果如下:

因此,会执行到ProtocolFilterWrapper#buildInvokerChain,该函数会对服务进行调用链跟踪:

所有的负载均衡、容错策略等都是在这里绑定的。 7.如果有多个注册中心,将会循环执行步骤6,将URL转换为Invoker对象,然后添加到一个List,分别进行注册之后,然后判断最后一个注册中心url是否有效,针对多订阅的场景,URL中添加cluster参数,默认使用org.apache.dubbo.rpc.cluster.support.registry.ZoneAwareCluster策略,使用org.apache.dubbo.rpc.cluster.Cluster#join将多个Invoker对象封装一个虚拟的Invoker中,否则如果最后一个注册中心是无效的,直接封装Invoker对象。 8.创建服务代理ProxyFactory#getProxy(org.apache.dubbo.rpc.Invoker<T>),因为ProxyFactory是一个适配类。那么同样这里会调用ProxyFactory$Adaptive#getProxy,这里最终就是返回一个代理服务的Invoker对象。

至此,我们的消费端的绑定远程zk的服务就已经结束了。 那么,我们在调用服务器方法的时候服务器端和客户端都是如何处理的呢?下节我们将继续分析。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2020-03-02 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 启动流程
    • 1. new ReferenceConfig
      • 2. ReferenceConfig#get
      相关产品与服务
      微服务引擎 TSE
      微服务引擎(Tencent Cloud Service Engine)提供开箱即用的云上全场景微服务解决方案。支持开源增强的云原生注册配置中心(Zookeeper、Nacos 和 Apollo),北极星网格(腾讯自研并开源的 PolarisMesh)、云原生 API 网关(Kong)以及微服务应用托管的弹性微服务平台。微服务引擎完全兼容开源版本的使用方式,在功能、可用性和可运维性等多个方面进行增强。
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档