【dubbo】-001dubbo的基本介绍

引言:服务调用框架的概述 大系统按照服务或者功能拆分成多个子系统。 1. 服务化的优点 (1) 拆分之后每个系统可以单独部署,业务简单,方便扩容; (2)有大量可重用模块便于开放新的业务; 2.服务化得缺点 (1) 分拆后,系统之间还是必须要打交道,越往底层的系统,调用它的客户方越多,要求底层系统必须具有超大规模的容量和非常高的可用性 (2) 拆分后的系统通讯问题,两种中间系统,一、 实时调用中间件(如:淘宝HSF、 阿里Dubbo);二、异步消息通知中间件(如淘宝的Notify)
一、基本概念 Dubbo 是阿里巴巴公司开源的一个高性能优秀的 分布式服务框架, 高性能的 RPC远程过程调用方案,SOA服务治理方案,可以和 Spring框架无缝集成。 主要核心部件:(1) 远程通讯( Remoting): 网络通信框架,实现了 sync-over-async ( 同步 异步 )和 request-response( 请求的响应 ) 消息机制 (2) RPC: 一个远程过程调用的抽象,支持 负载均衡 、 容灾 和集群功能 (3) R egistry: 服务目录框架用于 服务的注册 和服务事件 发布和订阅

二、Dubbo工作原理

【dubbo】-001dubbo的基本介绍
文章图片



dubbo服务介绍 (1) Provider暴露服务方称之为“服务提供者”。 服务提供者向注册中心 注册其提供的服务,并汇报调用时间到监控中心,此时间不包含网络开销 (2) Consumer调用远程服务方称之为“服务消费者”。 服务消费者 向注册中心获取服务提供者地址列表 , 并根据 负载算法直接调用提供者,同时汇报调用时间到监控中心,此时间包含网络开销 (3) Registry服务注册与发现的中心目录服务称之为“服务注册中心” 注册中心负责 服务地址的注册与查找,相当于目录服务,服务提供者和消费者只在 启动时与注册中心交互,注册中心不转发请求,压力较小(4) Monitor统计服务的调用次调和调用时间的日志服务称之为“服务监控中心” 监控中心负责统计各 服务调用次数,调用时间等,统计先在内存汇总后每分钟一次发送到 监控中心服务器,并以 报表展示


dubbo不同服务间的联系和区别 (1) 注册中心,服务提供者,服务消费者三者之间均为 长连接,监控中心除外 (2)注册中心通过 长连接感知服务提供者的存在, 服务提供者宕机, 注册中心将立即 推送事件通知 消费者 (3) 注册中心和监控中心全部宕机, 不影响已运行的 提供者和消费者, 消费者在本地 缓存了提供者列表 (4) 注册中心和监控中心都是可选的, 服务消费者可以直连服务提供者
dubbo健壮性 (1)监控中心宕掉不影响使用,只是丢失部分采样数据 (2) 数据库宕掉后,注册中心仍能通过缓存提供服务列表查询,但不能注册新服务 (3)注册中心对等集群,任意一台宕掉后,将自动切换到另一台 (4)注册中心全部宕掉后,服务提供者和服务消费者仍能通过本地缓存通讯 (5)服务提供者无状态,任意一台宕掉后,不影响使用 (6)服务提供者全部宕掉后,服务消费者应用将无法使用,并无限次重连等待服务提供者恢复
dubbo伸缩性 (1)注册中心为对等集群,可动态增加机器部署实例,所有客户端将自动发现新的注册中心 (2 )服务提供者无状态,可动态 增加机器部署实例, 注册中心将 推送新的 服务提供者信息给 消费者
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)去注册中心订阅自己的服务。 NettyServer-》MultiMessageHandler-》HeartbeatHandler-》AllDispatcher-》DecodeHandler-》HeaderExchangeHandler-》DubboProtocol.requestHandler-》EchoFilter-》ClassLoaderFilter-》GenericFilter-》ContextFilter-》ExceptionFilter-》TimeoutFilter-》MonitorFilter-》TraceFilter-》实际service。
(3)consumer启动过程
consumer的启动过程是通过ReferenceConfig的get方法进行的,具体步骤是:
(1)通过新建RemoteRegistry来建立与注册中心的连接。
(2)新建RegistryDirectory并向注册中心订阅服务,RegistryDirectory用以维护注册中心获取的服务相关信息。
(3)创建代理类,发起consumer远程调用时,实际调用的是InvokerInvocationHandler。
consumer端发起调用时,实际调用经过的类是: InvokerInvocationHandler-》MockClusterInvoker(如果配置了Mock,则直接调用本地Mock类)-》FailoverClusterInvoker(负载均衡,容错机制,默认在发生错误的情况下,进行两次重试)-》RegistryDirectory$InvokerDelegete-》ConsumerContextFilter-》FutureFilter-> DubboInvoker

Dubbo使用的设计模式 【【dubbo】-001dubbo的基本介绍】 (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方法,执行监听器方法。
(5)动态代理模式
Dubbo扩展jdk spi的类ExtensionLoader的Adaptive实现是典型的动态代理实现。Dubbo需要灵活地控制实现类,即在调用阶段动态地根据参数决定调用哪个实现类,所以采用先生成代理类的方法,能够做到灵活的调用。生成代理类的代码是ExtensionLoader的createAdaptiveExtensionClassCode方法。代理类的主要逻辑是,获取URL参数中指定参数的值作为获取实现类的key。

英文单词介绍: Monitor: 监控 invoke : 调用 subscribe / s?b?skra?b/订阅 notify [?not??fa?]通知

三、dubbo如何使用
(1) 生产者一端配置 < bean id = "userService" class = "com.ai.dubbo.provider.impl.UserServiceImpl" /> < bean id = "orderService" class = "com.ai.dubbo.provider.impl.OrderServiceImpl" /> < dubbo:service interface = "com.ai.dubbo.provider.UserService" ref = "userService" /> < dubbo:service interface = "com.ai.dubbo.provider.OrderService" ref = "orderService" /> (2) 消费者一端配置 < dubbo:reference id = "userService" interface = "com.ai.dubbo.provider.UserService" /> < dubbo:reference id = "orderService" interface = "com.ai.dubbo.provider.OrderService" />
四、dubbo能做什么 (1) 透明化远程调用 --像调用本地方法一样调用远程方法 --只需要简单配置,没有任何API侵入 (2)软负载均衡和容错机制 --可以内网替代F5等硬件负载均衡器,降低成本,减少单点 (3) 服务自动注册 和发现 --不在需要写死 服务提供者地址, 注册中心基于接口查询服务提供者的IP地址,并能 平滑增加或者删除服务提供者


参考资料: http://www.open-open.com/news/view/1442a5c http://www.open-open.com/doc/view/9ed50c3098474e60821b6f313c7719c8 【梁飞技术博客】 http://javatar.iteye.com/ 【dubbo源码阅】http://attend.iteye.com/blog/1311524 【阿里中间件博客】http://jm-blog.aliapp.com/?p=3138

    推荐阅读