服务引用是服务的消费方向注册中心订阅服务提供方提供的服务地址后向服务提供方引用服务的过程。

服务的应用方在spring的配置实例如下:

<dubbo:referenceid="demoService"interface="com.alibaba.dubbo.demo. DemoService"/>

如上配置spring在容器启动的时候会解析自定义的schema元素<dubbo: reference/>转换成dubbo内部数据结构ReferenceBean

ReferenceBean除了继承了配置的抽象类来处理配置信息外,它还实现spring容器的一些接口,这里我们分析下 FactoryBean, 首先它对于spring来说是个bean,参与Bean创建的所有生命周期,关键在于spring的bean工厂 beanFactory.getBean(“demoService”)获取的bean的时候会判断下是不是FactoryBean的实例,如果是调 factoryBean.getObject()返回,否则返回bean。

我们对于远程调用获取的demoService其实并不是想要ReferenceBean这个对象实例本身,我们是想获取对远程调用的代理,能够通 过这个代理服务调用远程服务。这里就是通过factoryBean.getObject()来创建引用返回基于DemoService接口的代理给引用, 对用户透明dubbo封装了复杂实现。

创建代理的过程:

1.      获取消费者配置

2.      获取配置的注册中心,通过配置中心配置拼装URL,线上应该是个配置中心集群

3.      遍历注册中心List<URL>集合

加载监控中心URL,如果配置了监控中心在注册中心url加上MONITOR_KEY

根据配置的引用服务参数给注册中URL上加上REFER_KEY

4.      遍历注册中心List<URL>集合,这里注册中心url包含了monitorUrl和referUrl

protocol.refer(interface,url)调用protocol引用服务返回invoker可执行对象(这个invoker并不 是简单的DubboInvoker, 而是由RegistryProtocol构建基于目录服务的集群策略Invoker, 这个invoker可以通过目录服务list出真正可调用的远程服务invoker)

对于注册中心Url设置集群策略为AvailableCluster, 由AvailableCluster将所有对象注册中调用的invoker伪装成一个invoker

5.      通过代理工厂创建远程服务代理返回给使用着proxyFactory.getProxy(invoker);

procotol.refer(interface, url) 引用服务的过程

1.      经过ProtocolListenerWrapper, ProtocolFilterWrapper由于是注册中心url调用RegistryProtocol.refer

2.      获取注册中心协议zookeeper, redis, 还是dubbo, 并根据注册中心协议通过注册器工厂RegistryFactory.getRegistry(url)获取注册器Registry用来跟注册中心交互

3.      根据配置的group分组

4.      创建注册服务目录RegistryDirectory并设置注册器

5.      构建订阅服务的subscribeUrl

6.      通过注册器registry向注册中心注册subscribeUrl消费端url

7.      目录服务registryDirectory.subscribe(subscribeUrl)订阅服务(这里我们以开源版本zookeeper为注册中心为例来讲解, dubbo协议的注册中心有点不一样)

其实内部也是通过注册器registry.subscribe(url,this) 这里this就是registryDirectory它实现了NotifyListener。

服务提供者在向zookeeper注册服务/dubbo/com.alibaba.dubbo.demo.DemoService/providers/节点下写下自己的URL地址

服务消费者向zookeepr注册服务/dubbo/com.alibaba.dubbo.demo.DemoService/consumers/节点下写下自己的URL地址

服务消费者向zookeeper 订阅服务/dubbo/com.alibaba.dubbo.demo.DemoService/ providers /节点下所有服务提供者URL地址

Zookeeper通过watcher机制实现对节点的监听,节点数据变化通过节点上的watcher回调客户端, 重新生成对服务的refer

在订阅的过程中通过获取/dubbo/com.alibaba.dubbo.demo.DemoService/providers /下的所有服务提供者的urls(类似dubbo://10.33. 37.8:20880/com.alibaba.dubbo.demo.DemoService?anyhost=true& application=demo-consumer&check=false&dubbo=2.0.0& generic=false&interface=com.alibaba.dubbo.demo.DemoService& methods=sayHello&owner=william&pid=7356&side=consumer& timestamp=1416971340626),主动回调NotifyListener来根据urls生成对服务提供者的引用生成可执行 invokers,供目录服务持有着,

看下如下RegistryDirectory.notify(urls)方法中的代码实现

8.      通过cluster.join(directory) 合并invoker并提供集群调用策略

DubboProtocol.refer过程:

1.      经过ProtocolListenerWrapper, ProtocolFilterWrapper构建监听器链和过滤器链。

2.      DubboProtocol根据url获取ExchangeClient对象,如果是share存在就返回不存在创建新对象不是share直接创建。ExchangeClient是底层通信的客户端,对于通信层的创建功能不在这里讲解。

3.      创建DubboInvoker, 这个invoker对象包含对远程服务提供者的长链接,是真正执行远程服务调用的可执行对象

4.      将创建的invoker返回给目录服务

官方文档的应用服务的序列图

活动图

【DUBBO】Dubbo原理解析-服务引用的更多相关文章

  1. 2、Dubbo源码解析--服务发布原理(Netty服务暴露)

    一.服务发布 - 原理: 首先看Dubbo日志,截取重要部分: 1)暴露本地服务 Export dubbo service com.alibaba.dubbo.demo.DemoService to ...

  2. Dubbo 源码分析 - 服务引用

    1. 简介 在上一篇文章中,我详细的分析了服务导出的原理.本篇文章我们趁热打铁,继续分析服务引用的原理.在 Dubbo 中,我们可以通过两种方式引用远程服务.第一种是使用服务直联的方式引用服务,第二种 ...

  3. dubbo refrence bean(服务引用)

    在xml上写一个dubbo标签就可以把远程的服务引用到本地使用: <dubbo:reference id="buyFoodService" interface="c ...

  4. Dubbo源码(四) - 服务引用(消费者)

    前言 本文基于Dubbo2.6.x版本,中文注释版源码已上传github:xiaoguyu/dubbo 上一篇文章,讲了Dubbo的服务导出: Dubbo源码(三) - 服务导出(生产者) 本文,咱们 ...

  5. 【DUBBO】Dubbo原理解析-服务发布

    转载:http://blog.csdn.net/quhongwei_zhanqiu/article/details/41651205 服务发布方在spring的配置文件中配置如下: <bean ...

  6. dubbo框架揭秘之服务引用

    ApplicationConfig config = new ApplicationConfig("hello-worldp"); RegistryConfig reg = new ...

  7. dubbo框架揭秘之服务发布

    通常情况下是通过Spring配置的方式去实现服务的发布,为了方便调试,我就不采用Spring配置的方式. DemoService demo = new DemoServiceImpl(); Appli ...

  8. Dubbo 源码分析 - 服务调用过程

    注: 本系列文章已捐赠给 Dubbo 社区,你也可以在 Dubbo 官方文档中阅读本系列文章. 1. 简介 在前面的文章中,我们分析了 Dubbo SPI.服务导出与引入.以及集群容错方面的代码.经过 ...

  9. Dubbo(一):Dubbo运行原理

    前言: 在开始入门Javaweb时,学的基本都是MVC开发模式,一个项目基本上就是model,view,controller三层.但是随着系统的服务逐渐加多,SOA模式更加适合目前项目开发.而SOA模 ...

随机推荐

  1. unity屏幕坐标转世界坐标结果为(0,0,0)

    代码: wv转出来一直为(0,0,0),卡了好久,问别人说要转化的屏幕坐标Z不能为0 阿西吧!特此记录

  2. Js 操作 Cookies

    <script language=javascript> // cookie其实是一个key=value就是一个cookie而不是 //获得coolie 的值 function cooki ...

  3. torch 深度学习(5)

    torch 深度学习(5) mnist torch siamese deep-learning 这篇文章主要是想使用torch学习并理解如何构建siamese network. siamese net ...

  4. Lua学习笔记1,基本数据类型

    1.字符串的连接使用的是  .. ,如 print(123 .. 44) 输出 12344 print ('a' .. 'b') 输出 ab print(123 .. 44)这句的时候 .. 两边要空 ...

  5. laravel中Crypt加密方法

    使用Crypt::encrypt对数据进行加密,要引入 use Illuminate\Support\Facades\Crypt;;  对使用Crypt::encrypt加密的数据进行解密的方法时:C ...

  6. 002——vue小结

    1.new 一个vue对象的时候你可以设置他的属性,其中最重要的包括三个,分别是:data,methods,watch. 2.其中data代表vue对象的数据,methods代表vue对象的方法,wa ...

  7. zuul 性能分析

    引用几篇博客, 后续整理自己心得 Zuul 性能测试 https://blog.csdn.net/u013815546/article/details/69669165 VisualVM 使用 htt ...

  8. Week11《java程序设计》作业总结

    Week11<java程序设计>作业总结 1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结多线程相关内容. 答: 2. 书面作业 本次PTA作业题集多线程 1. 源代码 ...

  9. 2018.11.15 RF antenna impedance-matching

    We have studied the impedance-matching of RF transmission line between the antenna and the RX / TX m ...

  10. TeamView

    1.TeamView TeamViewer是一个能在任何防火墙和NAT代理的后台用于远程控制,桌面共享和文件传输的简单且快速的解决方案.为了连接到另一台计算机,只需要在两台计算机上同时运行 TeamV ...