`
san_yun
  • 浏览: 2663597 次
  • 来自: 杭州
文章分类
社区版块
存档分类
最新评论

如何更好地学习dubbo源代码

 
阅读更多

http://jm.taobao.org/2013/11/14/3138/

 

很荣幸,作为这样一款业界使用率和好评率出众的RPC框架的维护者,今天这个文章主要是想帮助那些热爱开源的同学,更好的来研究dubbo的源代码。

 

一、Dubbo整体架构

1、Dubbo与Spring的整合
Dubbo在使用上可以做到非常简单,不管是Provider还是Consumer都可以通过Spring的配置文件进行配置,配置完之后,就可以像使用spring bean一样进行服务暴露和调用了,完全看不到dubbo api的存在。这是因为dubbo使用了spring提供的可扩展Schema自定义配置支持。在spring配置文件中,可以像、这样进行配置。META-INF下的spring.handlers文件中指定了dubbo的xml解析类:DubboNamespaceHandler。像前面的被解析成ServiceConfig,被解析成ReferenceConfig等等。
2、jdk spi扩展
由于Dubbo是开源框架,必须要提供很多的可扩展点。Dubbo是通过扩展jdk spi机制来实现可扩展的。具体来说,就是在META-INF目录下,放置文件名为接口全称,文件中为key、value键值对,value为具体实现类的全类名,key为标志值。由于dubbo使用了url总线的设计,即很多参数通过URL对象来传递,在实际中,具体要用到哪个值,可以通过url中的参数值来指定。
Dubbo对spi的扩展是通过ExtensionLoader来实现的,查看ExtensionLoader的源码,可以看到Dubbo对jdk spi做了三个方面的扩展:

(1)jdk spi仅仅通过接口类名获取所有实现,而ExtensionLoader则通过接口类名和key值获取一个实现;

(2)Adaptive实现,就是生成一个代理类,这样就可以根据实际调用时的一些参数动态决定要调用的类了。

(3)自动包装实现,这种实现的类一般是自动激活的,常用于包装类,比如Protocol的两个实现类:ProtocolFilterWrapper、ProtocolListenerWrapper。
3、url总线设计
Dubbo为了使得各层解耦,采用了url总线的设计。我们通常的设计会把层与层之间的交互参数做成Model,这样层与层之间沟通成本比较大,扩展起来也比较麻烦。因此,Dubbo把各层之间的通信都采用url的形式。比如,注册中心启动时,参数的url为:
registry://0.0.0.0:9090?codec=registry&transporter=netty
这就表示当前是注册中心,绑定到所有ip,端口是9090,解析器类型是registry,使用的底层网络通信框架是netty。

二、Dubbo启动过程

Dubbo分为注册中心、服务提供者(provider)、服务消费者(consumer)三个部分。
1、注册中心启动过程
注册中心的启动过程,主要看两个类:RegistrySynchronizer、RegistryReceiver,两个类的初始化方法都是start。
RegistrySynchronizer的start方法:

(1)把所有配置信息load到内存;

(2)把当前注册中心信息保存到数据库;

(3)启动5个定时器。
5个定时器的功能是:
(1)AutoRedirectTask,自动重定向定时器。默认1小时运行1次。如果当前注册中心的连接数高于平均值的1.2倍,则将多出来的连接数重定向到其他注册中心上,以达到注册中心集群的连接数均衡。
(2)DirtyCheckTask,脏数据检查定时器。作用是:分别检查缓存provider、数据库provider、缓存consumer、数据库consumer的数据,清除脏数据;清理不存活的provider和consumer数据;对于缓存中的存在的provider或consumer而数据库不存在,重新注册和订阅。
(3)ChangedClearTask,changes变更表的定时清理任务。作用是读取changes表,清除过期数据。
(4)AlivedCheckTask,注册中心存活状态定时检查,会定时更新registries表的expire字段,用以判断注册中心的存活状态。如果有新的注册中心,发送同步消息,将当前所有注册中心的地址通知到所有客户端。
(5)ChangedCheckTask,变更检查定时器。检查changes表的变更,检查类型包括:参数覆盖变更、路由变更、服务消费者变更、权重变更、负载均衡变更。
RegistryReceiver的start方法:启动注册中心服务。默认使用netty框架,绑定本机的9090端口。最后启动服务的过程是在NettyServer来完成的。接收消息时,抛开dubbo协议的解码器,调用类的顺序是

 

NettyHandler-》NettyServer-》MultiMessageHandler-》HeartbeatHandler-》AllDispatcher-》
DecodeHandler-》HeaderExchangeHandler-》RegistryReceiver-》RegistryValidator-》RegistryFailover-》RegistryExecutor。


2、provider启动过程
provider的启动过程是从ServiceConfig的export方法开始进行的,具体步骤是:
(1)进行本地jvm的暴露,不开放任何端口,以提供injvm这种形式的调用,这种调用只是本地调用,不涉及进程间通信。
(2)调用RegistryProtocol的export。
(3)调用DubboProtocol的export,默认开启20880端口,用以提供接收consumer的远程调用服务。
(4)通过新建RemoteRegistry来建立与注册中心的连接。
(5)将服务地址注册到注册中心。
(6)去注册中心订阅自己的服务。
3、consumer启动过程
consumer的启动过程是通过ReferenceConfig的get方法进行的,具体步骤是:
(1)通过新建RemoteRegistry来建立与注册中心的连接。
(2)新建RegistryDirectory并向注册中心订阅服务,RegistryDirectory用以维护注册中心获取的服务相关信息。
(3)创建代理类,发起consumer远程调用时,实际调用的是InvokerInvocationHandler。

 

三、实际调用过程
consumer端发起调用时,实际调用经过的类是:
1、consumer:

 

InvokerInvocationHandler-》MockClusterInvoker(如果配置了Mock,则直接调用本地Mock类)-》FailoverClusterInvoker(负载均衡,容错机制,默认在发生错误的情况下,进行两次重试)-》RegistryDirectory$InvokerDelegete-》ConsumerContextFilter-》FutureFilter->DubboInvoker


2、provider:

 

 

NettyServer-》MultiMessageHandler-》HeartbeatHandler-》AllDispatcher-》DecodeHandler-》HeaderExchangeHandler-》DubboProtocol.requestHandler-》EchoFilter-》ClassLoaderFilter-》GenericFilter-》ContextFilter-》ExceptionFilter-》TimeoutFilter-》MonitorFilter-》TraceFilter-》实际service。


四、Dubbo使用的设计模式
1、工厂模式
ServiceConfig中有个字段,代码是这样的:

 

 

private static final Protocol protocol = ExtensionLoader.getExtensionLoader(Protocol.class).getAdaptiveExtension();


Dubbo里有很多这种代码。这也是一种工厂模式,只是实现类的获取采用了jdk spi的机制。这么实现的优点是可扩展性强,想要扩展实现,只需要在classpath下增加个文件就可以了,代码零侵入。另外,像上面的Adaptive实现,可以做到调用时动态决定调用哪个实现,但是由于这种实现采用了动态代理,会造成代码调试比较麻烦,需要分析出实际调用的实现类。
2、装饰器模式
Dubbo在启动和调用阶段都大量使用了装饰器模式。以Provider提供的调用链为例,具体的调用链代码是在ProtocolFilterWrapper的buildInvokerChain完成的,具体是将注解中含有group=provider的Filter实现,按照order排序,最后的调用顺序是

 

 

EchoFilter-》ClassLoaderFilter-》GenericFilter-》ContextFilter-》ExceptionFilter-》
TimeoutFilter-》MonitorFilter-》TraceFilter。


更确切地说,这里是装饰器和责任链模式的混合使用。例如,EchoFilter的作用是判断是否是回声测试请求,是的话直接返回内容,这是一种责任链的体现。而像ClassLoaderFilter则只是在主功能上添加了功能,更改当前线程的ClassLoader,这是典型的装饰器模式。
3、观察者模式
Dubbo的provider启动时,需要与注册中心交互,先注册自己的服务,再订阅自己的服务,订阅时,采用了观察者模式,开启一个listener。注册中心会每5秒定时检查是否有服务更新,如果有更新,向该服务的提供者发送一个notify消息,provider接受到notify消息后,即运行NotifyListener的notify方法,执行监听器方法。
4、动态代理模式
Dubbo扩展jdk spi的类ExtensionLoader的Adaptive实现是典型的动态代理实现。Dubbo需要灵活地控制实现类,即在调用阶段动态地根据参数决定调用哪个实现类,所以采用先生成代理类的方法,能够做到灵活的调用。生成代理类的代码是ExtensionLoader的createAdaptiveExtensionClassCode方法。代理类的主要逻辑是,获取URL参数中指定参数的值作为获取实现类的key。

分享到:
评论

相关推荐

    Dubbo源代码(2.8.4)

    Dubbo是阿里巴巴开源的一款高性能、轻量级的Java服务治理框架,它主要专注于服务调用、负载均衡、服务发现、流量控制以及容错等核心功能。...通过深入研究,开发者可以更好地利用Dubbo来构建高效、可靠的分布式系统。

    eclipse 中实现dubbo provider、customer源代码及zookeeper、dubbo-admin压缩包

    在本压缩包中,你将找到关于如何在Eclipse环境中实现Dubbo服务提供者(Provider)和服务消费者...通过实践这些源代码,你将能够熟练地在Eclipse中搭建和运行Dubbo服务,同时加深对分布式系统和RPC框架的理解。

    Dubbo源码(注释版)

    Dubbo是中国阿里巴巴公司开源的一款高性能、轻量级的Java服务框架,它主要专注于服务治理,包括服务注册、发现、调用、负载均衡、容错、...通过学习源码,可以更好地利用和定制Dubbo,提升微服务架构的效率和稳定性。

    DubboM:Dubbo源代码修改版

    【DubboM:Dubbo源代码修改版】 DubboM是一个基于阿里巴巴的开源分布式服务框架Dubbo进行二次开发的版本。这个项目的核心目标是优化原生Dubbo的功能,以适应更广泛的业务场景,并且可能包含了特定的性能改进、功能...

    Dubbo监控系统配置

    为了更好地管理和监控Dubbo服务,Dubbo提供了一个名为“Dubbo Admin”的可视化管理平台,可以帮助开发者直观地了解服务状态和服务调用情况。 #### 二、Dubbo监控系统的部署与配置 ##### 2.1 部署Dubbo Admin 根据...

    dubbo2.0源码解读

    通过深入学习这些知识点,开发者可以更好地运用Dubbo解决实际问题,优化系统性能,同时也能为构建更复杂、更稳定的分布式系统奠定坚实基础。对于希望提升自己在微服务领域的技能的开发者来说,《Dubbo 2.0 源码解读...

    dubbo使用例子 dubbo使用例子

    通过对这些资源的深入研究,你可以更好地理解和掌握Dubbo的实际应用。 总之,Dubbo作为一个强大的分布式服务框架,其使用涉及到服务的定义、实现、注册、消费等多个环节,通过合理的配置和实践,我们可以利用它来...

    手写 dubbo

    【手写 Dubbo 知识点详解】...在这个过程中,可以参考已有的开源实现,如 Dubbo 的源代码,以便更好地理解和学习。同时,这个过程也是对个人编程技巧和系统设计能力的锻炼,对于提升自身在 IT 领域的专业水平大有裨益。

    dubbo-dubbo-2.5.9(Dubbo-admin管理平台的安装)

    【Dubbo-dubbo-2.5.9:深入理解Dubbo-admin管理平台的安装】 Dubbo,由阿里巴巴开源,是一款高性能、轻...正确安装和使用Dubbo-admin 2.5.9,可以帮助我们更好地管理和优化基于Dubbo的服务,提升系统的稳定性和效率。

    dubbo源码分析pdf.zip

    通过这两本书的学习,开发者不仅可以掌握Dubbo的基本使用,还能深入理解其内部工作原理,从而在实际项目中更好地应用和定制Dubbo,提升微服务架构的设计和实施能力。对于Java开发者而言,这是一份宝贵的资源,能助其...

    dubbo源码解析2

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

    dubbo-admin打包好的war包,下载就可以用

    这里的【标题】提到的是"Dubbo-admin打包好的war包,下载就可以用",这意味着你无需从源代码构建,可以直接部署这个预编译的WAR文件到你的应用服务器上,便于快速启用Dubbo的服务管理功能。 【描述】中提到,用户在...

    内含Dubbo的管理控制台dubbo-admin

    “工具”标签表明了dubbo-admin是一个实用的工具,旨在帮助开发者更好地管理和运维基于Dubbo构建的微服务系统。它提供了图形化的用户界面,使得操作更加直观和便捷,包括查看服务状态、监控服务性能、配置服务路由和...

    我的dubbo demo

    【标题】"我的dubbo demo" 是一个个人保留的Dubbo示例项目,它旨在帮助开发者更好地理解和使用Dubbo框架。Dubbo是中国阿里巴巴开源的一款高性能、轻量级的服务治理框架,它提供了服务注册、服务发现、调用链路监控、...

    dubbo学习视频教程

    学习源码可以帮助你更好地定制化服务,解决实际问题,并提升自己的编程能力。 【标签】"工具"可能涵盖了使用的一些辅助开发工具,比如IDEA、Maven、Git等,以及一些用于调试、测试和部署的工具和技巧。 虽然提供的...

    ares-remoting:mini版dubbo源代码,分布式服务注册与调用原理解释

    《ares-remoting:迷你版Dubbo源代码解析——分布式服务注册与调用揭秘》 在IT行业中,分布式服务已经成为大型系统架构的核心组成部分,而Dubbo作为阿里巴巴开源的一款高性能、轻量级的服务治理框架,备受业界关注...

    dubbo-2.7.8:dubbo-2.7.8原始码

    现在,我们正在收集dubbo用户信息,以帮助我们更好地改善Dubbo。 请为您提供有关 ,谢谢:)建筑学特征基于透明接口的RPC 智能负载均衡自动服务注册和发现高扩展性运行时流量路由可视化服务治理入门以下代码段来自 。...

    visitor-manage 访客管理系统,学习dubbo架构使用.zip

    在这个项目中,开发者巧妙地结合了SpringBoot框架,使得系统具备更高的开发效率和更好的微服务管理能力。 一、Dubbo框架解析 Dubbo是Java世界的明星级服务治理框架,它提供了服务注册、服务发现、负载均衡、熔断...

    dubbo-2.8.4.jar 下载

    源码阅读可以帮助开发者更好地排查问题,进行性能优化,甚至扩展Dubbo以满足特定需求。 在实际使用中,开发人员通常会将`dubbo-2.8.4.jar`添加到项目的类路径中,而`dubbo-2.8.4-sources.jar`则可以配合IDE(如...

    pafa5 dubbo admin

    这样的设计有助于开发者更好地整合现有系统,并实现与传统J2EE应用的平滑对接。 【标签】"dubbo admin" 指出了这个项目的核心关注点在于Dubbo的管理后台,即Dubbo Admin。Dubbo Admin通常包括服务的注册与发现、...

Global site tag (gtag.js) - Google Analytics