`
m635674608
  • 浏览: 5028036 次
  • 性别: Icon_minigender_1
  • 来自: 南京
社区版块
存档分类
最新评论

Dubbo原理解析-注册中心之基于dubbo协议的简单注册中心实现

 
阅读更多

基于dubbo协议开源只是给出了默认一个注册中心实现SimpleRegistryService, 它只是一个简单实现,不支持集群,就是利用Map<String/*ip:port*/, Map<String/*service*/, URL>来存储服务地址, 具体不在啰嗦了,请读者翻看源代码,可作为自定义注册中的参考。

注册中心启动

SimpleRegistryService本身也是作为一个dubbo服务暴露。

<dubbo:protocolport="9090" />

<dubbo:service interface="com.alibaba.dubbo.registry.RegistryService"ref="registryService" registry="N/A" ondisconnect="disconnect"callbacks="1000">

<dubbo:methodname="subscribe"><dubbo:argument index="1" callback="true"/></dubbo:method>

<dubbo:methodname="unsubscribe"><dubbo:argument index="1" callback="false"/></dubbo:method>

</dubbo:service>

<bean id="registryService"class="com.alibaba.dubbo.registry.simple.SimpleRegistryService" />

上面是暴露注册中心的dubbo服务配置,

定义了注册中心服务的端口号

发布RegistryService服务, registry属性是”N/A”代表不能获取注册中心,注册中心服务的发布也是一个普通的dubbo服务的发布,如果没有配置这个属性它也会寻找注册中心,去通过注册中心发布,因为自己本身就是注册中心,直接对外发布服务,外部通过ip:port直接使用。

服务发布定义了回调接口, 这里定义了subscribe的第二个入参类暴露的回调服务供注册中心回调,用来当注册的服务状态变更时反向推送到客户端。

Dubbo协议的注册中心的暴露以及调用过程过程跟普通的dubbo服务的其实是一样的,可能跟绝大多数服务的不同的是在SimpleRegistryService在被接收订阅请求subscribe的时候,同时会refer引用调用方暴露的NotifyListener服务,当有注册数据变更时自动推送

生产者发布服务

Dubbo协议向注册中心发布服务:当服务提供方,向dubbo协议的注册中心发布服务的时候,是如何获取,创建注册中心的,如何注册以及订阅服务的,下面我们来分析其流程。

看如下配置发布服务:

<dubbo:registry protocol=”dubbo” address="127.0.0.1:9090" />

<beanid="demoService" class="com.alibaba.dubbo.demo.provider.DemoServiceImpl"/>

<dubbo:serviceinterface="com.alibaba.dubbo.demo.DemoService" ref="demoService"/>

1. 指定了哪种的注册中心,是基于dubbo协议的,指定了注册中心的地址以及端口号

2. 发布DemoService服务,服务的实现为DemoServiceImpl

每个<dubbo:service/>在spring内部都会生成一个ServiceBean实例,ServiceBean的实例化过程中调用export方法来暴露服务

1. 通过loadRegistries获取注册中心registryUrls

registry://127.0.0.1:9090/com.alibaba.dubbo.registry.RegistryService?application=demo-provider&dubbo=2.5.4-SNAPSHOT&owner=william&pid=7084&registry=dubbo&timestamp=1415711791506

用统一数据模型URL表示:

protocol=registry表示一个注册中心url

注册中心地址127.0.0.1:9090

调用注册中心的服务RegistryService

注册中心协议是registry=dubbo

。。。。。。

2. 构建发布服务的URL

dubbo://192.168.0.102:20880/com.alibaba.dubbo.demo.DemoService?anyhost=true&application=demo-provider&dubbo=2.5.4-SNAPSHOT&generic=false&interface=com.alibaba.dubbo.demo.DemoService&loadbalance=roundrobin&methods=sayHello&owner=william&pid=7084&side=provider&timestamp=1415712331601

发布协议protocol =dubbo

服务提供者的地址为192.168.0.102:20880

发布的服务为com.alibaba.dubbo.demo.DemoService

。。。。。。

3. 遍历registryUrls向注册中心注册服务

给每个registryUrl添加属性key为export,value为上面的发布服务url得到如下registryUrl

registry://127.0.0.1:9098/com.alibaba.dubbo.registry.RegistryService?application=demo-provider&dubbo=2.5.4-SNAPSHOT&export=dubbo%3A%2F%2F192.168.0.102%3A20880%2Fcom.alibaba.dubbo.demo.DemoService%3Fanyhost%3Dtrue%26application%3Ddemo-provider%26dubbo%3D2.5.4-SNAPSHOT%26generic%3Dfalse%26interface%3Dcom.alibaba.dubbo.demo.DemoService%26loadbalance%3Droundrobin%26methods%3DsayHello%26owner%3Dwilliam%26pid%3D7084%26side%3Dprovider%26timestamp%3D1415712331601&owner=william&pid=7084&registry=dubbo&timestamp=1415711791506

4. 由发布的服务实例,服务接口以及registryUrl为参数,通过代理工厂proxyFactory获取Invoker对象,Invoker对象是dubbo的核心模型,其他对象都向它靠拢或者转换成它。

5. 通过Protocol对象暴露服务protocol.export(invoker)

通过DubboProtocol暴露服务的监听(不是此节内容)

通过RegistryProtocol将服务地址发布到注册中心,并订阅此服务

RegistryProtocol.export(Invoker)暴露服务

1. 调DubboProtocol暴露服务的监听

2. 获取注册中心getRegistry(Invoker)

URL转换, 由Invoker获取的url是registryURL它的协议属性用来选择何种的Protocol实例如RegistryProtocol, DubboProtocol或者RedisProtocol等等。 这里要通过URL去选择何种注册中心,所以根据registry=dubbo属性,重新设置url的协议属性得registryUrl

dubbo: //127.0.0.1:9098/com.alibaba.dubbo.registry.RegistryService?application=demo-provider&dubbo=2.5.4-SNAPSHOT& export=dubbo%3A%2F%2F192.168.0.102%3A20880%2Fcom.alibaba.dubbo.demo.DemoService%3Fanyhost%3Dtrue%26application%3Ddemo-provider%26dubbo%3D2.5.4-SNAPSHOT%26generic%3Dfalse%26interface%3Dcom.alibaba.dubbo.demo.DemoService%26loadbalance%3Droundrobin%26methods%3DsayHello%26owner%3Dwilliam%26pid%3D5040%26side%3Dprovider%26timestamp%3D1415715706560&owner=william&pid=5040&timestamp=1415715706529

RegistryFactory.getRegistry(url) 通过工厂类创建注册中心,RegistryFactory通过dubbo的spi机制获取对应的工厂类, 这里的是基于dubbo协议的注册中心,所以是DubboRegistryFactory

3. 获取发布url 就是registryUrl的export参数的值

registryProviderUrl=dubbo://10.33.37.7:20880/com.alibaba.dubbo.demo.DemoService?anyhost=true&application=demo-provider&dubbo=2.5.4-SNAPSHOT&generic=false&interface=com.alibaba.dubbo.demo.DemoService&loadbalance=roundrobin&methods=sayHello&owner=william&pid=6976&side=provider&timestamp=1415846958825

4. DubboRegistry.register(registryProviderUrl)

通过注册器向注册中心注册服务

这里注意registryProviderUrl的并没有设置category属性, 在注册中心UrlUtils.ismatch(conuumerUrl, providerUrl)比较的时候,providerUrl的category属性取默认值providers,

这点消费者订阅的时候会指定订阅的url的category=providers,去判断有没有注册的提供者。

5. 构建订阅服务overrideProviderUrl,我们是发布服务

provider:/ /10.33.37.7:20880/com.alibaba.dubbo.demo.DemoService?anyhost=true&application=demo-provider&category=configurators&check=false&dubbo=2.5.4-SNAPSHOT&generic=false&interface=com.alibaba.dubbo.demo.DemoService&loadbalance=roundrobin&methods=sayHello&owner=william&pid=6432&side=provider&timestamp=1415847417663

6. 构建OverrideListener它实现与NotifyLisener,当注册中心的订阅的url发生变化时回调重新export

7. registry.subscribe(overrideProviderUrl, OverrideListener), 注册器向注册中心订阅overrideProviderUrl,同时将Override Listener暴露为回调服务,当注册中心的overrideProviderUrl数据发生变化时回调,

注册器DubboRegistry的registry,subscribe, unRegistry, unSubscribe都类似, 是一个dubbo的远程服务调用

DubboRegistryFactory创建注册中心过程

1. 根据传入registryUrl重新构建

移除EXPORT_KEY REFER_KEY

添加订阅回调参数

dubbo://127.0.0.1:9098/com.alibaba.dubbo.registry.RegistryService?application=demo-provider&callbacks=10000&connect.timeout=10000&dubbo=2.5.4-SNAPSHOT& interface=com.alibaba.dubbo.registry.RegistryService&lazy=true&methods=register,subscribe,unregister,unsubscribe,lookup&owner=william&pid=8492&reconnect=false&sticky=true&subscribe.1.callback=true&timeout=10000&timestamp=1415783872554&unsubscribe.1.callback=false

2. 根据url 注册服务接口构建注册目录对象RegistryDircectory,实现了NotiyfLisener,这里NotiyfLisener实现主要是根据urls去refer引用远程服务RegistryService得到对应的Invoker,当urls变化时重新refer;目录服务可以列出所有可以执行的Invoker

3. 利用cluster的join方法,将Dirctory的多个Invoker对象伪装成一个Invoker对象, 这里默认集群策略得到FailoverClusterInvoker

4. FailoverClusterInvoker利用ProxyFactory获取到RegistryService服务的代理对象

5. 由RegistryService服务的代理对象和FailoverClusterInvoker构建dubbo协议的注册中心注册器DubboRegistry

6. RegistryDircectory设置注册器DubboRegistry,设置dubbo的协议

7. 调用 RegistryDircectory的notify(urls)方法

主要是根据registryUrls, 引用各个注册中心的RegistryService服务实现,将引用的服务按key=menthodName/value=invoker缓存起来, 目录服务Directory.list(Invocation)会列出所调用方法的所有Invoker , 一个Invoker代表对一个注册中心的调用实体。

8. 订阅注册中心服务, 服务的提供者调注册中心的服务RegistryService属于消费方, 所以订阅服务的url的协议是consumer

consumer: //192.168.0.102/com.alibaba.dubbo.registry.RegistryService?application=demo-provider&callbacks=10000&connect.timeout=10000&dubbo=2.5.4-SNAPSHOT&interface=com.alibaba.dubbo.registry.RegistryService&lazy=true&methods=register,subscribe,unregister,unsubscribe,lookup&owner=william&pid=6960&reconnect=false&sticky=true &subscribe.1.callback=true&timeout=10000&timestamp=1415800789364& unsubscribe.1.callback=false

订阅的目的在于在注册中心的数据发送变化的时候反向推送给订阅方

directory.subscribe(url)最终调用注册中心的RegsryService远程服务, 它是一个普通的dubbo远程调用。要说跟绝大多数dubbo远程调用的区别:url的参数subscribe.1.callback=true 它的意思是RegistryService的subscribe方法的第二个参数NotifyListener暴露为回调服务; url的参数 unsubscribe.1.callback=false 的意思是RegistryService的 unsubscribe 方法的第二个参数NotifyListener暴露的回调服务销毁。

这里dubbo协议的注册中心调注册中心的服务采用的默认集群调用策略是FailOver,选择一台注册中心,只有当失败的时候才重试其他服务器,注册中心实现也比较简单不具备集群功能, 如果想要初步的集群功能可以选用BroadcastCluster它至少向每个注册中心遍历调用注册一遍

消费者引用服务

< dubbo:registry protocol = ”dubbo” address = "127.0.0.1:9098" />

< dubbo:reference id = "demoService" interface = "com.alibaba.d ubbo.demo.DemoService" />

1. 指定了哪种的注册中心,是基于dubbo协议的,指定了注册中心的地址以及端口号

2. 引用远程DemoService服务

每个<dubbo:reference/>标签spring加载的时候都会生成一个Referenc eBean。

如上图ReferenceBean实现了spring的FactoryBean接口, 实现了此接口的Bean通过spring的BeanFactory.getBean(“beanName”)获取的对象不是配置的bean本身而是通过FactoryBean.getObject()方法返回的对象,此接口在spring内部被广泛使用,用来获取代理对象等等。这里getObjec t方法用来生成对远程服务调用的代理

1. loadRegistries()获取配置的注册中心的registryUrls

2. 遍历registryUrls集合,给registryUrl加上refer key就是要引用的远程服务

[ registry ://127.0.0.1:9098/com.alibaba.dubbo.registry.RegistryService?application=demo-consumer&dubbo=2.0.0&pid=2484& refer =application%3Ddemo-consumer%26dubbo%3D2.0.0%26interface%3Dcom.alibaba.dubbo.demo.DemoService%26methods%3DsayHello%26pid%3D2484%26side%3Dconsumer%26timestamp%3D1415879965901&registry=dubbo&timestamp=1415879990670]

3. 遍历registryUrls集合,使用Protocol.refer(interface,regist ryUrl)的到可执行对象invoker

4. 如果注册中心有多个的话, 通过集群策略Cluser.join()将多个invoke r伪装成一个可执行invoker, 这里默认使用available策略

5. 利用代理工厂生成代理对象proxyFactory.getProxy(invoker)

Protocol.refer过程流程

1. 根据传入的registryUrl是用来选择RegistryProcol它的协议属性是registry, 下面要选择使用哪种注册中心所以要根据REGISTRY_KEY属性重新设置registrUrl

dubbo: //127.0.0.1:9098/com.alibaba.dubbo.registry.RegistryService?application=demo-consumer&dubbo=2.0.0&pid=4524&refer=application%3Ddemo-consumer%26dubbo%3D2.0.0%26interface%3Dcom.alibaba.dubbo.demo.DemoService%26methods%3DsayHello%26pid%3D4524%26side%3Dconsumer%26timestamp%3D1415881461048&timestamp=1415881461113

2. 根据registrUrl利用RegistryFactory获取注册器(过程跟暴露服务那边一样), 这里是dubbo协议得到的是注册器是DubboRegistry

引用并订阅注册中心服务,

3. 构建引用服务的subscribeUrl

consumer ://10.5.24.221/ 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=8536&side=consumer&timestamp=1415945205031

并通过注册器向注册中心注册消费方, 主要这里的category是consume rs

4. 构建目录服务RegistryDirectory,

构建订阅消费者订阅url,这里主要 category=providers 去注册中心寻找注册的服务提供者

consumer://10.33.37.4/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=9692&side=consumer&timestamp=1415967547508

向注册中心订阅消费方,注册中心根据消费者传入的url找到匹配的服务提供者url (注意:这里服务提供者没有设置 category ,注册中心对于没有设置的默认取 providers ) dubbo://10.33.37.4:20880/com.alibaba.dubbo.demo.DemoService?anyhost=true&application=demo-provider&dubbo=2.5.4-SNAPSHOT&generic=false&interface=com.alibaba.dubbo.demo.DemoService&loadbalance=roundrobin&methods=sayHello&owner=william&pid=9828&side=provider&timestamp=1415968955329

然后注册中心回调服务消费者暴露的回调接口来对服务提供者的服务进行引用refer生成对应的可执行对象invoker。服务提供者与服务的消费建立连接,

5. 通过Cluster合并directory中的invokers, 返回可执行对象invoker

6. ProxyFactory.getProxy(invoker) 创建代理对象返回给业务方使用

这里dubbo协议的注册中心调注册中心的服务采用的默认集群调用策略是FailOver,选择一台注册中心,只有当失败的时候才重试其他服务器,注册中心实现也比较简单不具备集群功能, 如果想要初步的集群功能可以选用BroadcastCluster它至少向每个注册中心遍历调用注册一遍http://www.tuicool.com/articles/a677ze

 

分享到:
评论

相关推荐

    一.dubbox(dangdang V2.8.4)+springBoot(1.4.2.RELEASE)+dubbo-monitor-web 监控项目源码

    7. **源码解析**:深入研究dubbox和springBoot的源码,理解它们的工作原理,这对于优化服务性能和解决故障至关重要。 8. **实战演练**:通过实际操作,如搭建环境、编写服务提供者和消费者、配置监控中心,将理论...

    dubbo-samples-master_dubbo_breathgz9_

    《Dubbo实战:基于dubbo-samples-master的深度解析》 Dubbo,作为阿里巴巴开源的一款高性能、轻量级的服务治理框架,一直以来都是Java开发者在分布式服务领域的首选工具。本教程将深入探讨`dubbo-samples-master`...

    dubbo-demo-maven版

    总结,"dubbo-demo-maven版"项目为我们提供了一个完整的、基于Maven构建的Dubbo示例,涵盖了Dubbo的核心功能,包括服务提供、消费、注册、协议、监控等。通过这个项目,开发者可以快速上手Dubbo,理解分布式服务的...

    dubbo-go-3.0.5

    通过分析这些组件的实现,可以理解其工作原理,比如如何实现服务注册、服务调用、失败重试等机制。 此外,Dubbo-Go 的配置中心允许动态调整服务配置,如修改服务版本、调整超时时间等,这对于微服务架构中的快速...

    dubbo源码解析2

    - **7.2.2 DubboRegistryFactory创建注册中心过程**:具体实现注册中心创建过程。 - **7.2.3 注册中心启动**:启动注册中心的相关步骤。 - **7.2.4 生产者发布服务** - **7.2.4.1 Export发布服务流程**:服务提供者...

    服务治理中间件 dubbo原理解析

    Dubbo支持多种注册中心协议,其中Dubbo协议注册中心是Dubbo原生支持的注册中心实现,而Zookeeper协议注册中心则是广泛使用的第三方注册中心实现,它通过Zookeeper的树形结构来管理服务状态。 ### 集群&容错 集群和...

    服务治理中间件dubbo原理解析

    服务治理中间件Dubbo是阿里巴巴基于开源思想使用Java语言实现的高性能RPC框架,它支持服务的注册与发现、负载均衡、容错处理等服务治理功能。Dubbo采用微内核架构加插件体系的设计模式,通过SPI(Service Provider ...

    dubbo-dubbo-3.2.6.zip

    1. **服务注册与发现**:Dubbo支持基于Zookeeper、Eureka等注册中心的服务注册与发现,实现了服务的动态管理和负载均衡,使得服务提供者和服务消费者能够透明地进行交互。 2. **高性能RPC**:Dubbo采用了NIO异步...

    Dubbo RPC框架原理解析和源码

    Dubbo协议是默认且推荐的,它基于TCP,实现了高性能、轻量级的二进制协议。其他协议各有优缺点,适用于不同的场景。 **四、负载均衡** Dubbo内置了多种负载均衡策略,如Random、RoundRobin、LeastActive等。这些...

    dubbo源码包

    1. **协议模块**:Dubbo支持多种通信协议,如基于Netty的Dubbo协议、HTTP、RMI等,dubbo-2.4.3-sources.jar包含了这些协议的实现细节。 2. **序列化模块**:Dubbo支持多种序列化方式,如Hessian2、FastJson、...

    dubbo-2.5.3源码

    Dubbo协议基于Netty实现,使用二进制协议进行序列化,提高了数据传输效率。 五、负载均衡 Dubbo提供了多种负载均衡策略,如Random、RoundRobin、LeastActive等,可根据实际需求选择合适的策略。 六、容错机制 ...

    dubbo-2.5.6源码zip

    Dubbo支持基于Zookeeper、Consul等配置中心的实现。 7. **协议与序列化** - Dubbo支持多种通信协议,如Dubbo、HTTP、RMI等,每种协议的实现都在Protocol模块中。 - 序列化是网络通信的重要环节,Dubbo提供了多种...

    dubbo压测插件(不需要依赖,支持jmeter各个版本)

    其工作原理主要是通过解析和传递Dubbo协议,模拟大量并发请求来评估Dubbo服务在高负载情况下的性能和稳定性。 这个插件的使用非常简单,用户只需将提供的`jmeter-dubbo-2.7.1-jar-with-dependencies.jar.zip`文件...

    dubbo源码解析2.0.7z

    Dubbo作为Java领域最知名的分布式服务框架之一,其设计理念、实现原理以及在实际应用中的优化策略都是开发者们关注的焦点。这份解析文档旨在帮助读者理解Dubbo的工作流程,提升对分布式系统设计的理解,为实际开发...

    dubbo+zookeeper+tomcat+dubbo-monitor完整示例工程包括相应jar包.zip

    本篇将深入解析一个基于Dubbo、Zookeeper、Tomcat以及Dubbo-Monitor的完整示例工程,帮助你理解这些组件如何协同构建高效、可扩展的服务架构。 首先,我们来了解一下Dubbo。Dubbo是阿里巴巴开源的一款高性能、轻量...

    基于Netty实现了dubbo rpc

    【标题】基于Netty实现Dubbo RPC 在分布式系统中,RPC(Remote Procedure Call)是一种常见且重要的通信机制,它允许一个程序调用另一个在不同进程中运行的程序,就像调用本地函数一样简单。Dubbo作为阿里巴巴开源...

    dubbo_rpc_hession_rmi

    在IT行业中,分布式服务框架是实现大规模系统高可用、高性能的关键技术之一,而Dubbo、Hessian和RMI则是其中的三个重要组件。本篇将深入解析这些技术及其在实际应用中的示例。 首先,Dubbo是阿里巴巴开源的一款高...

    dubbo-2.5.4官网源码下载

    - 通过Zookeeper、Eureka等注册中心实现服务的注册和发现。源码中会包含注册中心的客户端接口和实现,以及服务元数据的管理。 4. **动态配置与远程调用**: - Dubbo支持动态配置,服务的元数据可以在运行时更改,...

    dubbo-master.zip

    《深入剖析Dubbo框架——基于dubbo-master源码解析》 Dubbo,作为阿里巴巴开源的一款高性能、轻量级的服务治理框架,一直以来都是Java开发者们学习和应用的重点。它以其强大的服务治理能力,如服务注册与发现、负载...

Global site tag (gtag.js) - Google Analytics