【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模 ...
随机推荐
- SpringBoot下的值注入
在我们实际开发项目中,经常会遇到一些常量的配置,比如url,暂时不会改变的字段参数,这个时候我们最好是不要直接写死在代码里的,因为这样编写的程序,应用扩展性太差了,我们可以直接写在配置文件中然后通过配 ...
- tail命令 | head命令
tail -f -n 50 log.txt 循环读取文件log.txt的后50行 head -n 50 log.txt 显示文件的前n行
- tkinter模块常用参数
tkinter模块常用参数 1.使用tkinter.Tk() 生成主窗口(root=tkinter.Tk()):root.title('标题名') 修改框体的名字,也可在创建时使用class ...
- Linux 系统启动过程,Linux 系统目录结构
一.Linux 系统启动过程 linux启动时我们会看到许多启动信息. Linux系统的启动过程并不是大家想象中的那么复杂,其过程可以分为5个阶段: 内核的引导. 运行 init. 系统初始化. 建立 ...
- ansible入门一(Ansible介绍及安装部署)
本节内容: 运维工具 Ansible特性 Ansible架构图和核心组件 安装Ansible 演示使用示例 一.运维工具 作为一个Linux运维人员,需要了解大量的运维工具,并熟知这些工具的差异,能够 ...
- SC用法
转自:(http://blog.163.com/yf_handsome/blog/static/20238174200802495124164/) SC使用这样的语法: 1. SC [Serverna ...
- Java进阶3. 内存回收机制
Java进阶3. 内存回收机制 20131029 前言: 学过C++的都知道,C++中内存需要程序员自己维护.说道这里,很多开发的同学就感觉很痛苦,当他转向Java的时候,就会说你看Java多好啊,程 ...
- gitblit-禁用用户
使用管理员账号(此处演示使用admin)登录到系统 右上角,找到用户菜单 再用户列表,找到要进行权限管理的用户,(演示alex) 禁用用户,取消权限 验证已经禁用 pull 权限被禁止
- java中a++和++a的区别详解
java中的++操作无论在前还是在后,都是在变量自身的值加1,接下来将具体描述两者的区别 int a =5; int b =a++; System.out.println(b); 1.通俗易懂的理解是 ...
- 6个变态的C语言程序
转载自 陈浩 coolshell.cn 下面的六个程序片段主要完成这些事情: 输出Hello, World 混乱C语言的源代码 下面的所有程序都可以在GCC下编译通过,只有最后一个需要动用C++的编译 ...