`

(原创)Dubbo源码之消费者创建代理

 
阅读更多

ReferenceBean中

afterPropertiesSet方法:获取当前项目所有的具体配置项(Registry,Module,Application,Monitor)。
spring为bean复制的时候,调用getObject方法。

getObject方法:
调用get方法

get方法:
调用ReferenceConfig类中的init方法

ReferenceConfig中

init方法:
获取当前消费者全局配置,根据当前配置生成代理,具体配置项为:
side=consumer, 
application=demo-consumer,
methods=sayHello, 
dubbo=2.0.0, 
pid=6440, 
interface=com.alibaba.dubbo.demo.DemoService, 
timestamp=1481015195590

createProxy方法: 
创建临时路径
temp://localhost?application=demo-consumer&dubbo=2.0.0&interface=com.alibaba.dubbo.demo.DemoService&methods=sayHello&pid=6440&side=consumer&timestamp=1481015195590
通过注册中心配置拼装URL,执行loadRegistries方法,拼接的url结果为:
registry://192.168.10.232:2181/com.alibaba.dubbo.registry.RegistryService?application=demo-consumer&backup=192.168.10.233:2181,192.168.10.234:2181&dubbo=2.0.0&pid=6440&registry=zookeeper&timestamp=1481015705299
引用远程服务,调用RegistryProtocol类中的refer方法,参数为服务提供者的接口interface com.alibaba.dubbo.demo.DemoService以及由注册中心拼接的上面的URL。

RegistryProtocol中
refer方法:
通过RegistryFactory类的getRegistry方法,
URL修改为:zookeeper://192.168.10.232:2181/com.alibaba.dubbo.registry.RegistryService?application=demo-consumer&backup=192.168.10.233:2181,192.168.10.234:2181&dubbo=2.0.0&interface=com.alibaba.dubbo.registry.RegistryService&pid=6440&timestamp=1481015705299
根据URL获取service服务key为zookeeper://192.168.10.232:2181/com.alibaba.dubbo.registry.RegistryService
通过URLzookeeper://192.168.10.232:2181/com.alibaba.dubbo.registry.RegistryService?application=demo-consumer&backup=192.168.10.233:2181,192.168.10.234:2181&dubbo=2.0.0&interface=com.alibaba.dubbo.registry.RegistryService&pid=6440&timestamp=1481015705299
创建zookeeper客户端,并连接zk主机,将该registry缓存。执行doRefer方法,参数为
cluster,创建的集群策略对象默认使用AvailableCluster
registry,当前连接的注册中心对象
type,服务提供者接口interface com.alibaba.dubbo.demo.DemoService
url,zookeeper://192.168.10.232:2181/com.alibaba.dubbo.registry.RegistryService?application=demo-consumer&backup=192.168.10.233:2181,192.168.10.234:2181&dubbo=2.0.0&pid=6440&refer=application%3Ddemo-consumer%26dubbo%3D2.0.0%26interface%3Dcom.alibaba.dubbo.demo.DemoService%26methods%3DsayHello%26pid%3D6440%26side%3Dconsumer%26timestamp%3D1481015195590&timestamp=1481015705299

doRefer方法:
创建RegistryDirectory对象,将RegistryDirectory对象中的routers中添加MockInvokersSelector对象
serviceType设置为:interface com.alibaba.dubbo.demo.DemoService
serviceKey设置为:com.alibaba.dubbo.registry.RegistryService
queryMap设置为:{side=consumer, application=demo-consumer, methods=sayHello, dubbo=2.0.0, pid=6440, interface=com.alibaba.dubbo.demo.DemoService, timestamp=1481015195590}
overrideDirectoryUrl设置为:zookeeper://192.168.10.232:2181/com.alibaba.dubbo.registry.RegistryService?application=demo-consumer&dubbo=2.0.0&interface=com.alibaba.dubbo.demo.DemoService&methods=sayHello&pid=6440&side=consumer&timestamp=1481015195590
serviceMethods设置为sayHello
设置registry对象为传来的registry,设置协议为dubbo。
根据本地URL等信息创建订阅URL:
consumer://192.168.10.107/com.alibaba.dubbo.demo.DemoService?application=demo-consumer&dubbo=2.0.0&interface=com.alibaba.dubbo.demo.DemoService&methods=sayHello&pid=6440&side=consumer&timestamp=1481015195590
进入FailbackRegistry类中执行register方法。参数为消费者调用service的URL
consumer://192.168.10.107/com.alibaba.dubbo.demo.DemoService?application=demo-consumer&category=consumers&check=false&dubbo=2.0.0&interface=com.alibaba.dubbo.demo.DemoService&methods=sayHello&pid=10412&side=consumer&timestamp=1481070964540

FailbackRegistry中
register方法:
缓存消费者调用service的URL,也就是消费者的描述消费行为的URL
向服务器端发送注册请求,执行doRegister方法,参数为消费行为URL

doRegister方法:
进入ZookeeperRegistry类中,create方法添加节点,分为持久节点与临时节点两种,其中持久节点路径为:
/dubbo/com.alibaba.dubbo.demo.DemoService/consumers
临时节点为:
/dubbo/com.alibaba.dubbo.demo.DemoService/consumers/consumer%3A%2F%2F192.168.10.107%2Fcom.alibaba.dubbo.demo.DemoService%3Fapplication%3Ddemo-consumer%26category%3Dconsumers%26check%3Dfalse%26dubbo%3D2.0.0%26interface%3Dcom.alibaba.dubbo.demo.DemoService%26methods%3DsayHello%26pid%3D10412%26side%3Dconsumer%26timestamp%3D1481070964540
与zk进行长连接以后,回到RegistryProtocol类中的doRefer方法中。

RegistryProtocol中
doRefer方法:将之前创建的directory执行订阅方法,directory.subscribe方法,参数为订阅URL
订阅URL为消费者消费行为URL的修改:
原:consumer://192.168.10.107/com.alibaba.dubbo.demo.DemoService?application=demo-consumer&dubbo=2.0.0&interface=com.alibaba.dubbo.demo.DemoService&methods=sayHello&pid=10412&side=consumer&timestamp=1481070964540
现:consumer://192.168.10.107/com.alibaba.dubbo.demo.DemoService?application=demo-consumer&category=providers,configurators,routers&dubbo=2.0.0&interface=com.alibaba.dubbo.demo.DemoService&methods=sayHello&pid=10412&side=consumer&timestamp=1481070964540
订阅执行FailbackRegistry类中的subscribe方法。

FailbackRegistry中
subscribe方法:
为该消费者的注册中心notified的属性添加监听类集合,key为消费者URL:
consumer://192.168.10.107/com.alibaba.dubbo.demo.DemoService?application=demo-consumer&category=providers,configurators,routers&dubbo=2.0.0&interface=com.alibaba.dubbo.demo.DemoService&methods=sayHello&pid=10412&side=consumer&timestamp=1481070964540
value为new ConcurrentHashMap<URL, Set<NotifyListener>>(),Set集合中存放监听listener监听器。然后执行doSubscribe方法。

doSubscribe方法
参数为消费者消费行为URL与RegistryProtocol类中doRefer方法中创建的RegistryDirectory。执行ZookeeperRegistry类中的subscribe方法。

ZookeeperRegistry中
doSubscribe方法:
参数与FailbackRegistry中doSubscribe方法的参数一样。
通过消费者消费行为URL转化获得消费者对应的服务提供者的URL:
原:consumer://192.168.10.107/com.alibaba.dubbo.demo.DemoService?application=demo-consumer&category=providers,configurators,routers&dubbo=2.0.0&interface=com.alibaba.dubbo.demo.DemoService&methods=sayHello&pid=10412&side=consumer&timestamp=1481070964540
现:/dubbo/com.alibaba.dubbo.demo.DemoService/providers。
根据此目录获取绑定再zk上的监听器,zkListeners,如果没有,则在zkListeners上创建,格式为key-value,key为:
consumer://192.168.10.107/com.alibaba.dubbo.demo.DemoService?application=demo-consumer&category=providers,configurators,routers&dubbo=2.0.0&interface=com.alibaba.dubbo.demo.DemoService&methods=sayHello&pid=10412&side=consumer&timestamp=1481070964540
value为new ConcurrentHashMap<NotifyListener, ChildListener>(),
listener相关变量:
1、ZookeeperRegistry类中的变量
zkListeners
类型为ConcurrentHashMap<URL, ConcurrentMap<NotifyListener, ChildListener>>
2、从1中获取到的listeners,通过url获取url为:consumer://192.168.10.107/com.alibaba.dubbo.demo.DemoService?application=demo-consumer&category=providers,configurators,routers&dubbo=2.0.0&interface=com.alibaba.dubbo.demo.DemoService&methods=sayHello&pid=13152&side=consumer&timestamp=1481164403391
类型为ConcurrentMap<NotifyListener, ChildListener> 
3、从2中获取到的zkListener,key为2中的NotifyListener,NotifyListener为传来的RegistryDirectory
整体梳理(消费者URL,(消费者所需的服务提供者的集合,监听器对象))
创建完监听器集合以及对应关系,执行zkClient.create方法,参数为/dubbo/com.alibaba.dubbo.demo.DemoService/providers和false,调用AbstractZookeeperClient中的create方法,false代表创建的是持久集合
添加之后,对该消费者在zk节点的加监听,执行zkClient.addChildListener方法,参数为消费者zk节点的path与listener,最终执行的是ZkclientZookeeperClient类中的addTargetChildListener方法,使用zkAPI的原生方法client.subscribeChildChanges(path, listener);
最后执行FailbackRegistry类中的notify方法,参数为
本地消费者URL:consumer://192.168.138.1/com.alibaba.dubbo.demo.DemoService?application=demo-consumer&category=providers,configurators,routers&dubbo=2.0.0&interface=com.alibaba.dubbo.demo.DemoService&methods=sayHello&pid=11040&side=consumer&timestamp=1481250787575
描述消费者与注册中心的RegistryDirectory
URLS:
dubbo://192.168.138.1:20880/com.alibaba.dubbo.demo.DemoService?anyhost=true&application=demo-provider&dubbo=2.0.0&generic=false&interface=com.alibaba.dubbo.demo.DemoService&loadbalance=roundrobin&methods=sayHello&owner=william&pid=10568&side=provider&timestamp=1481250727882
empty://192.168.138.1/com.alibaba.dubbo.demo.DemoService?application=demo-consumer&category=configurators&dubbo=2.0.0&interface=com.alibaba.dubbo.demo.DemoService&methods=sayHello&pid=11040&side=consumer&timestamp=1481250787575
empty://192.168.138.1/com.alibaba.dubbo.demo.DemoService?application=demo-consumer&category=routers&dubbo=2.0.0&interface=com.alibaba.dubbo.demo.DemoService&methods=sayHello&pid=11040&side=consumer&timestamp=1481250787575

FailbackRegistry中
notify方法跳转执行doNotify方法

doNotify方法:
最终执行AbstractRegistry中的notify方法

AbstractRegistry中:

notify方法:
执行RegistryDirectory中的notify

RegistryDirectory中:
notify方法:
执行refreshInvoker方法:
将传来的URL通过toInvokers方法转换为invoker,URL为:
dubbo://192.168.138.1:20880/com.alibaba.dubbo.demo.DemoService?anyhost=true&application=demo-provider&dubbo=2.0.0&generic=false&interface=com.alibaba.dubbo.demo.DemoService&loadbalance=roundrobin&methods=sayHello&owner=william&pid=10568&side=provider&timestamp=1481250727882

toInvokers方法:
因为之前没有获取过服务提供者的URL,所以缓存中没有,需要获取服务提供者,执行DubboProtocol类中的refer方法,

DubboProtocol中的
refer方法:
参数为:interface com.alibaba.dubbo.demo.DemoService
dubbo://192.168.138.1: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&loadbalance=roundrobin&methods=sayHello&owner=william&pid=10868&side=consumer&timestamp=1481252071784
创建DubboInvoker
首先通过URL获取zkClient执行getClients方法,参数为上面的参数,执行initClient方法

initClient方法:
调用Exchangers.connect(url ,requestHandler)方法。
URL:dubbo://192.168.138.1:20880/com.alibaba.dubbo.demo.DemoService?anyhost=true&application=demo-consumer&check=false&codec=dubbo&dubbo=2.0.0&generic=false&heartbeat=60000&interface=com.alibaba.dubbo.demo.DemoService&loadbalance=roundrobin&methods=sayHello&owner=william&pid=10868&side=consumer&timestamp=1481252071784
创建NettyClient并连接远程服务端,将转换的invoker加入缓存。
回到RegistryDirectory中的refreshInvoker方法。回到RegistryProtocol中doRefer方法。

RegistryProtocol中
doRefer方法:
将封装了与服务提供者的URL以及注册中的directory加入到Cluster中,将Cluster伪装成invoker,将invoker整合为demoService的代理,默认代理为JavassistProxyFactory创建代理。
创建InvokerInvocationHandler,将真正的服务提供者invoker加入到InvokerInvocationHandler中

分享到:
评论

相关推荐

    dubbo源码分析系列

    - 服务消费者引用:理解服务消费者如何查找并引用服务,包括URL参数解析、服务订阅和回调机制。 4. **负载均衡策略** - 负载均衡器:探讨Dubbo内置的各种负载均衡策略,如Random、RoundRobin、LeastActive等,...

    dubbo源码解析2

    在开始深入解析Dubbo源码之前,首先需要明确的是,Dubbo虽然代码量不算庞大,但是它涉及的技术领域非常广泛,对于初学者来说,可能需要具备一定的前置知识才能更好地理解和学习。以下是建议的学习路径: 1. **Java...

    dubbo源码分析pdf.zip

    1. **Dubbo架构设计**:书中详细介绍了Dubbo的整体架构,包括服务提供者、消费者、注册中心和服务监控等组件,以及它们之间的交互方式。理解这一部分有助于开发者把握Dubbo的工作流程。 2. **Remoting层解析**:...

    dubbo源码解析

    本文对dubbo源码进行了深入的解析,涵盖了dubbo的架构、核心机制分析、扩展点加载流程、代理机制、远程调用流程、集群和容错处理、监控机制等多个方面。通过阅读和理解这些内容,可以更好地掌握dubbo的内部工作机制...

    dubbo源码分享,可打包创建可视页面

    dubbo源码,打成war包后,将此war放入本地tomcat&gt;webapps目录下,启动tomcat(/bin/startup.bat) 为了防止端口占用,可以再/conf/server.xml 修改tomcat端口,我的是8088 tomcat自解压 如图这里写图片描述 打开...

    dubbo源码解析 1 pdf2.0

    2. HelloWorld例子:通过最简单的例子,理解Dubbo服务的提供者和消费者是如何交互的。 3. 源文件概述:对源码的各个模块和文件有一个概览,明白它们的作用和相互关系。 4. 核心机制分析:详细分析Dubbo的设计模式...

    dubbo2.0源码解读

    4. **HelloWorld例子**:这个简单的示例展示了如何使用Dubbo创建服务提供者和服务消费者。通过配置XML或API,定义接口、实现服务、启动服务提供者,然后在消费者端引用服务,完成调用。 5. **源文件概述**:Dubbo的...

    dubbo入门学习框架源码

    2. 服务消费者(Consumer):调用服务的实体,通过Dubbo接口消费服务。 3. 注册中心(Registry):存储服务提供者和服务消费者的元数据,实现服务的注册和发现。 4. 运行时监控(Monitor):收集服务的运行数据,...

    dubbo源码解析2.0.7z

    首先,Dubbo的核心组件包括服务提供者(Provider)、服务消费者(Consumer)、注册中心(Registry)和服务监控(Monitor)。在源码解析中,会详细介绍这些组件的交互过程,如服务注册与发现、调用链路的建立与跟踪,以及服务...

    dubbo-zookeeper springSpringMVC 一个生产者,多消费者 例子

    1.dubbo-zookeeper springSpringMVC 一个生产者,多消费者 例子 2. ssm-dubbo 源码 ssm-tomcat 里放的是 warbao ,程序包 zookeeper-3.4.9 zookeeper 免安装包 设置都是默认的 zookeeper 端口 2181 dubbo-...

    Dubbo 源码 阿里巴巴

    Dubbo 源码 阿里巴巴 这是最新的 源码大家学习一下!

    dubbo提供者消费者jar包

    在这个“dubbo2.4版本提供者provider消费者consumer jar包”中,包含了实现Dubbo服务提供者(Provider)和消费者(Consumer)功能的核心类库。 首先,我们要理解Dubbo的核心概念。服务提供者(Provider)是提供服务...

    apache dubbo 3.0.7源码

    - **代理模式**:Dubbo通过动态代理生成服务接口的客户端代理类,实现服务调用。 - **序列化**:支持多种序列化方式,如Hessian2、FastJson、Java自带的序列化等,负责将对象转换为可传输的数据格式。 - **网络...

    Dubbo+Dubbo生产者,Dubbo消费者+Dubbo消费者调用生产者的服务的小demo

    本项目案例“妻子”作为消费者去调用生产者(“丈夫”)的服务--洗碗 本项目需要注意 @DubboReference private HusbandService husbandService; @EnableDubbo @DubboService 这几个注解不能忘,否则会报错,或者...

    dubbo提供者消费者例子

    Dubbo 是阿里巴巴开源的一款高性能、轻量级的Java...通过这个实例,你可以了解到如何创建服务提供者和服务消费者,如何配置服务暴露和引用,以及如何进行服务的调用。这对于后续在实际项目中应用Dubbo会有很大的帮助。

    Dubbo源码分析之SPI

    通过以上机制,Dubbo能够实现对服务提供者、消费者、协议、注册中心等组件的动态扩展。这种高度可插拔的架构使得Dubbo能够适应各种复杂场景,同时降低了模块间的耦合度。 在实际应用中,理解并掌握Dubbo SPI的工作...

    dubbo源码解析2.01.pdf

    ### Dubbo源码解析知识点概览 #### 一、Dubbo简介与背景 - **背景**:Apache Dubbo是一款高性能、轻量级的开源服务框架,致力于提供高性能和透明化的RPC远程服务调用方案,以及SOA服务治理方案。Dubbo版本2.01在...

Global site tag (gtag.js) - Google Analytics