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

服务的应用方在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. git bash 出显错误不能用,怎么解决

    解决方法: 好像就是64的会出问题,其实32位的git也可以安装在64位的系统上. 将你64位的git卸掉了后,下载一个32位的git安装,就可以正常使用了, 当然,你的32位的出了错,卸了后也这样处 ...

  2. C++中输入输出十六进制八进制

    本文参考链接:https://www.cnblogs.com/hxsyl/archive/2012/09/18/2691693.html,经重新实验得此文 1.进制问题 默认情况下使用cin和cout ...

  3. c++复习要点

    自增和自减运算符有前缀和后缀两种形式,都会改变对象,所以不能对常量对象操作. 前缀形式返回改变后的对象,返回*this. 后缀形式返回改变之前的值,所以必须创建一个代表这个值的独立对象并返回它,是通过 ...

  4. spring boot 中logback多环境配置

    spring boot 配置logback spring boot自带了log打印功能,使用的是Commons logging 具体可以参考spring boot log 因此,我们只需要在resou ...

  5. 收集的几个好用的maven mirror

    <mirrors> <mirror> <id>jboss-public-repository-group</id> <mirrorOf>ce ...

  6. 常见浏览器bug(针对IE6及更低版本)及其修复方法

    常见bug及其修复方法有以下几种 1.双外边距浮动bug 双外边距浮动bug在IE6及更低版本中常见.所谓双外边距浮动bug是指使任何浮动元素上的外边距加倍.(见下图) 只要将元素的display属性 ...

  7. 2: 使用Prism初始化程序(纯汉语版)

    本篇内容讲解了Prism应用程序启动和运行都发生了什么.一个Pris应用程序在程序启动期间需要注册和配置——这被叫做引导应用程序.Prism引导过程包括创建和配置一个模块目录,创建一个例如Unity的 ...

  8. CF911B

    题解: 枚举一下x x<=min(a,b) 然后判断a/x+b/x是否>=x 代码: #include<bits/stdc++.h> using namespace std; ...

  9. OC-NSString

    ========================== 面向对象编程进阶和字符串 ========================== Δ一.类的设计模式—单例 [单例]程序允许过程中,有且仅有一块内存 ...

  10. Java虚拟机访问读写其他进程的数据--RandomAccessFile

    RandomAccessFile 是Java输入/输出流体系中功能最丰富的文件内容访问类,它提供了众多的方法来访问文件内容,它既可以读取文件内容,也可以向文件输出数据.并且它支持“任意访问”的方式,程 ...