【DUBBO】Dubbo原理解析-服务引用
服务引用是服务的消费方向注册中心订阅服务提供方提供的服务地址后向服务提供方引用服务的过程。
服务的应用方在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原理解析-服务引用的更多相关文章
- 2、Dubbo源码解析--服务发布原理(Netty服务暴露)
一.服务发布 - 原理: 首先看Dubbo日志,截取重要部分: 1)暴露本地服务 Export dubbo service com.alibaba.dubbo.demo.DemoService to ...
- Dubbo 源码分析 - 服务引用
1. 简介 在上一篇文章中,我详细的分析了服务导出的原理.本篇文章我们趁热打铁,继续分析服务引用的原理.在 Dubbo 中,我们可以通过两种方式引用远程服务.第一种是使用服务直联的方式引用服务,第二种 ...
- dubbo refrence bean(服务引用)
在xml上写一个dubbo标签就可以把远程的服务引用到本地使用: <dubbo:reference id="buyFoodService" interface="c ...
- Dubbo源码(四) - 服务引用(消费者)
前言 本文基于Dubbo2.6.x版本,中文注释版源码已上传github:xiaoguyu/dubbo 上一篇文章,讲了Dubbo的服务导出: Dubbo源码(三) - 服务导出(生产者) 本文,咱们 ...
- 【DUBBO】Dubbo原理解析-服务发布
转载:http://blog.csdn.net/quhongwei_zhanqiu/article/details/41651205 服务发布方在spring的配置文件中配置如下: <bean ...
- dubbo框架揭秘之服务引用
ApplicationConfig config = new ApplicationConfig("hello-worldp"); RegistryConfig reg = new ...
- dubbo框架揭秘之服务发布
通常情况下是通过Spring配置的方式去实现服务的发布,为了方便调试,我就不采用Spring配置的方式. DemoService demo = new DemoServiceImpl(); Appli ...
- Dubbo 源码分析 - 服务调用过程
注: 本系列文章已捐赠给 Dubbo 社区,你也可以在 Dubbo 官方文档中阅读本系列文章. 1. 简介 在前面的文章中,我们分析了 Dubbo SPI.服务导出与引入.以及集群容错方面的代码.经过 ...
- Dubbo(一):Dubbo运行原理
前言: 在开始入门Javaweb时,学的基本都是MVC开发模式,一个项目基本上就是model,view,controller三层.但是随着系统的服务逐渐加多,SOA模式更加适合目前项目开发.而SOA模 ...
随机推荐
- Hive 表结构操作
添加列 add columns alter table table_name add columns (id int comment '主键ID' ) ; 默认在表所有字段之后,分区字段之前. 替换 ...
- jshint options
jshint -W032 忽略if代码块后有多余的分号的提示 地址:jslinterrors.com/unnecessary-semicolon asi 忽略函数定义后必须加分号的提示 c ...
- Android----- 改变图标原有颜色 和 搜索框
本博客主要讲以下两点知识点 图标改变颜色:Drawable的变色,让Android也能有iOS那么方便的图片色调转换,就像同一个图标,但是有多个地方使用,并且颜色不一样,就可以用这个方法了. 搜索框: ...
- python的经典类与新式类
新式类:class Myclass(object): pass 经典类:class Myclass: pass 新式类里面加了一些新方法,例如重写父类: class A(object): def __ ...
- poj 1724 ROADS 很水的dfs
题意:给你N个城市和M条路和K块钱,每条路有话费,问你从1走到N的在K块钱内所能走的最短距离是多少 链接:http://poj.org/problem?id=1724 直接dfs搜一遍就是 代码: # ...
- IOS-CALayer(图层)
BWLayer.m // // BWLayer.m // IOS_0222_CALayer // // Created by ma c on 16/2/23. // Copyright © 2016年 ...
- C# 设计模式巩固 - 简单工厂模式
前言 设计模式的文章很多.鄙人不才文笔也不咋地.写这篇只为巩固下基础知识,万一不小心帮到了您,是我莫大的荣幸!写的不好欢迎码友指正,废话结束开始进入正题. 介绍 - 简单工厂模式 官方定义:(尴尬~貌 ...
- 那如何判断页面是在移动端还是PC端打开的
网上有很多方法,写的或难或简单,实际上一行代码就够了. window.location.href = /Android|webOS|iPhone|iPod|BlackBerry/i.test(navi ...
- awk与sed:一个关于多行处理的例子
前几天在CSDN上看到一个帖子http://bbs.csdn.net/topics/390848841,楼主贴了下面的问题: 例: 12345 67890 1234567890 123 4567890 ...
- c# 数据库批量插入数据SqlBulkCopy 示例
/// <summary> /// 批量插入数据 /// </summary> public static void SqlBulkInsert(DataTable dt, s ...