学习dubbo源代码

标签: 学习 dubbo 源代码 | 发表时间:2014-04-22 23:28 | 作者:weiboxie
出处:http://www.iteye.com

一、Dubbo整体架构

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

(1)jdkspi仅仅通过接口类名获取所有实现,而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协议的解码器,调用类的顺序是

1
2
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:

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

2、provider:

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

四、Dubbo使用的设计模式

1、工厂模式

ServiceConfig中有个字段,代码是这样的:

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

 

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

 

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

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



已有 0 人发表留言,猛击->> 这里<<-参与讨论


ITeye推荐



相关 [学习 dubbo 源代码] 推荐:

学习dubbo源代码

- - Java - 编程语言 - ITeye博客
1、Dubbo与Spring的整合. Dubbo在使用上可以做到非常简单,不管是Provider还是Consumer都可以通过Spring的配置文件进行配置,配置完之后,就可以像使用springbean一样进行服务暴露和调用了,完全看不到dubboapi的存在. 这是因为dubbo使用了spring提供的可扩展Schema自定义配置支持.

[原]Dubbo实例

- -
Dubbo是一个分布式服务框架,致力于提供高性能和透明化的RPC远程服务调用方案,以及SOA服务治理方案. Remoting: 网络通信框架,实现了sync-over-async 和 request-response 消息机制. RPC: 一个远程过程调用的抽象,支持负载均衡、容灾和集群功能. Registry: 服务目录框架用于服务的注册和服务事件发布和订阅.

DUBBO用户指南

- - 开源软件 - ITeye博客
随着互联网的发展,网站应用的规模不断扩大,常规的垂直应用架构已无法应对,分布式服务架构以及流动计算架构势在必行,亟需一个治理系统确保架构有条不紊的演进. 当网站流量很小时,只需一个应用,将所有功能都部署在一起,以减少部署节点和成本. 此时,用于简化增删改查工作量的 数据访问框架(ORM) 是关键. 当访问量逐渐增大,单一应用增加机器带来的加速度越来越小,将应用拆成互不相干的几个应用,以提升效率.

dubbo 问题整理

- - 行业应用 - ITeye博客
1 面试题:Dubbo中zookeeper做注册中心,如果注册中心集群都挂掉,发布者和订阅者之间还能通信么. 可以的,启动dubbo时,消费者会从zk拉取注册的生产者的地址接口等数据,缓存在本地. 每次调用时,按照本地存储的地址进行调用. 注册中心对等集群,任意一台宕掉后,会自动切换到另一台 . 注册中心全部宕掉,服务提供者和消费者仍可以通过本地缓存通讯 .

dubbo服务降级实现dubbo-plus/circuitbreaker at master · dubboclub/dubbo-plus · GitHub

- -
向注册中心写入动态配置覆盖规则:(通过由监控中心或治理中心的页面完成). 表示消费方对该服务的方法调用都直接返回null值,不发起远程调用. 屏蔽不重要服务不可用时对调用方的影响. 表示消费方对该服务的方法调用在失败后,再返回null值,不抛异常. 容忍不重要服务不稳定时对调用方的影响. Dubbo支持服务降级,并且支持当服务出现异常的时候进行服务降级处理,但是存在一下几个缺陷.

dubbo的安装和使用

- - CSDN博客云计算推荐文章
随着互联网的发展,网站应用的规模不断扩大,常规的垂直应用架构已无法应对,分布式服务架构以及流动计算架构势在必行,亟需一个治理系统确保架构有条不紊的演进. 当网站流量很小时,只需一个应用,将所有功能都部署在一起,以减少部署节点和成本. 此时,用于简化增删改查工作量的 . 数据访问框架(ORM) 是关键.

Dubbo基本原理机制

- - 开源软件 - ITeye博客
转自:http://blog.csdn.net/paul_wei2008/article/details/19355681 分布式服务框架:. –高性能和透明化的RPC远程服务调用方案. -Apache MINA 框架基于Reactor模型通信框架,基于tcp长连接. Dubbo缺省协议采用单一长连接和NIO异步通讯,.

dubbo处理文件上传

- - 开源软件 - ITeye博客
dubbo和hessian的maven依赖:. 服务提供者(项目名称:provider). 首先是web.xml配置(使用spring):. 最重要的applicationContext.xml :. 参考: dubbo hessian协议. .

dubbo中的Filter顺序

- - 互联网 - ITeye博客
最近发现dubbo的小 bug,顺便整理了一下dubbo中的Filter调用顺序及如何确定的. 服务提供方的过滤器被调用顺序:. EchoFilter->ClassLoaderFilter->GenericFilter->ContextFilter->(这4个是在代码中指定的). 服务消费方的过滤器顺序:.

谈Dubbo服务框架

- - 人月神话的BLOG
Dubbo 是阿里巴巴公司开源的一个高性能优秀的服务框架,使得应用可通过高性能的 RPC 实现服务的输出和输入功能,可以和 Spring框架无缝集成. 它最大的特点是按照分层的方式来架构,使用这种方式可以使各个层之间解耦合(或者最大限度地松耦合). 从服务模型的角度来看,Dubbo采用的是一种非常简单的模型,要么是提供方提供服务,要么是消费方消费服务,所以基于这一点可以抽象出服务提供方(Provider)和服务消费方(Consumer)两个角色.