dubbo源码愫读(1)dubbo总体架构

1、微服务简介

微服务是一种用于构建应用的架构方案。微服务架构有别于更为传统的单体式方案,可将应用拆分成多个核心功能。每个功能都被称为一项服务,可以单独构建和部署,这意味着各项服务在工作(和出现故障)时不会相互影响。

1.1、微服务架构的优势

微服务可通过分布式部署,大幅提升团队和日常工作效率。还可以并行开发多个微服务。这意味着更多开发人员可以同时开发同一个应用,进而缩短开发所需的时间。

  • 加速做好面市准备:
    由于开发周期缩短,微服务架构有助于实现更加敏捷的部署和更新。
  • 高度可扩展:
    随着某些服务的不断扩展,您可以跨多个服务器和基础架构进行部署,充分满足自身需求。
  • 出色的弹性:
    只要确保正确构建,这些独立的服务就不会彼此影响。这意味着,一个服务出现故障不会导致整个应用下线,这一点与单体式应用模型不同。
  • 易于部署:
    相对于传统的单体式应用,基于微服务的应用更加现代化而小巧,所以您无需为它们的部署操心。虽然对部署时的协作要求更高,但之后能获得巨大回报。
  • 易于访问:
    由于大型应用被拆分成了多个小型服务,所以开发人员能够更加轻松地理解、更新和增强这些服务,从而缩短开发周期(尤其是在搭配使用敏捷的开发方法时)。
  • 更加开放:
    由于使用了多语言 API,所以开发人员可以根据需要实现的功能,自由选用最适合的语言和技术。

1.2、所面临的挑战

复杂性和效率问题是基于微服务的架构所面临的挑战。

  • 构建:你必须花时间明确各个服务间的依赖关系。要知道,由于存在这些依赖关系,当您完成一个构建时,可能会触发多个其他构建。您还需要考虑微服务对于数据的影响。
  • 测试:集成测试和端到端测试可能会前所未有的难以实施,但却更加重要。根据您在架构相互支撑的服务时所采用的不同方式,架构中的一个部分出现故障,很可能会导致其他部分也随之出现故障。
  • 版本管理:在更新到新版本时,请记住:向后兼容性可能会因更新操作而失效。要解决这一问题,您可以利用条件逻辑来进行构建,但是构建会变得繁复、难以控制且快速。或者,您也可以为不同的客户端维护多个活跃版本,但是相关的维护和管理工作会变得更加庞杂。
  • 部署:没错,这也是一大挑战,至少是首次设置时所要面临的一大挑战。为了简化部署,您必须先大量投资于自动化,因为人工部署无法应对微服务的复杂性。请好好思考您要以何种方式以及怎样的顺序来部署各项服务。
  • 日志记录:使用分布式系统时,您需要利用集中式日志将所有相关信息集中到一处。否则,积累的日志数量将让您难以招架。
  • 监控:您必须通过一个集中式视图来了解整个系统的情况,以便找出问题的根源。
  • 调试:无法进行远程调试,因为这种方式无法涵盖数十个或数百个服务。不幸的是,关于应该如何进行调试,目前还没有标准答案。
  • 连接:请考虑使用服务探索功能,无论是集中式的还是集成式。

2、dubbo架构设计

2.1、dubbo结构图

9795603-cdbf003fa1bcca3b.png
dubbo结构图.png

节点角色说明:

  • Consumer(服务消费者):
    服务消费者启动后,会从注册中心查找服务提供者列表,并tcp连接到提供者服务器;当应用调用RPC接口时,服务消费者通过一定的路由算法,选择某个服务提供者进行通信,调用对应接口获取数据。同时,消费者会向注册中心订阅需要的服务,当订阅的服务有更新时,注册中心将通知对应的消费者。消费者也会定时向监控中心报告状态及统计数据等信息,以备监控中心进行监控统计等。

  • Provider(服务提供者):
    服务提供者启动之后,会将提供的服务信息注册到注册中心;其同时接受消费者的服务请求并定时将状态及统计信息同步到监控中心。

  • Container(服务容器):
    服务运行容器。

  • Register(注册中心):
    服务提供者先启动start,然后注册register服务。消费订阅subscribe服务,如果没有订阅到自己想获得的服务,它会不断的尝试订阅。新的服务注册到注册中心以后,注册中心会将这些服务通过notify到消费者。

  • Monitor(监控中心):
    这是一个监控,图中虚线表明Consumer 和Provider通过异步的方式发送消息至Monitor,Consumer和Provider会将信息存放在本地磁盘,平均1min会发送一次信息。Monitor在整个架构中是可选的(图中的虚线并不是可选的意思),Monitor功能需要单独配置,不配置或者配置以后,Monitor挂掉并不会影响服务的调用。

调用关系说明:

  • 0:服务容器负责启动,加载,运行服务提供者。
  • 1:服务提供者在启动时,向注册中心注册自己提供的服务。
  • 2:服务消费者在启动时,向注册中心订阅自己所需的服务。
  • 3:注册中心返回服务提供者地址列表给消费者,如果有变更,注册中心将基于长连接推送变更数据给消费者。
  • 4:服务消费者,从提供者地址列表中,基于软负载均衡算法,选一台提供者进行调用,如果调用失败,再选另一台调用。
  • 5:服务消费者和提供者,在内存中累计调用次数和调用时间,定时每分钟发送一次统计数据到监控中心。

2.2、dubbo总体架构

9795603-40ec2bb3ad139e3b.png
dubbo总体架构图.png

Dubbo框架设计一共划分了10个层,最上面的Service层是留给实际想要使用Dubbo开发分布式服务的开发者实现业务逻辑的接口层。图中左边淡蓝背景的为服务消费方使用的接口,右边淡绿色背景的为服务提供方使用的接口, 位于中轴线上的为双方都用到的接口。

下面,结合Dubbo官方文档,我们分别理解一下框架分层架构中,各个层次的设计要点:

  • 服务接口层(Service):该层是与实际业务逻辑相关的,根据服务提供方和服务消费方的业务设计对应的接口和实现。
  • 配置层(Config):对外配置接口,以ServiceConfig和ReferenceConfig为中心,可以直接new配置类,也可以通过spring解析配置生成配置类。
  • 服务代理层(Proxy):服务接口透明代理,生成服务的客户端Stub和服务器端Skeleton,以ServiceProxy为中心,扩展接口为ProxyFactory。
  • 服务注册层(Registry):封装服务地址的注册与发现,以服务URL为中心,扩展接口为RegistryFactory、Registry和RegistryService。可能没有服务注册中心,此时服务提供方直接暴露服务。
  • 集群层(Cluster):封装多个提供者的路由及负载均衡,并桥接注册中心,以Invoker为中心,扩展接口为Cluster、Directory、Router和LoadBalance。将多个服务提供方组合为一个服务提供方,实现对服务消费方来透明,只需要与一个服务提供方进行交互。
  • 监控层(Monitor):RPC调用次数和调用时间监控,以Statistics为中心,扩展接口为MonitorFactory、Monitor和MonitorService。
  • 远程调用层(Protocol):封将RPC调用,以Invocation和Result为中心,扩展接口为Protocol、Invoker和Exporter。Protocol是服务域,它是Invoker暴露和引用的主功能入口,它负责Invoker的生命周期管理。Invoker是实体域,它是Dubbo的核心模型,其它模型都向它靠扰,或转换成它,它代表一个可执行体,可向它发起invoke调用,它有可能是一个本地的实现,也可能是一个远程的实现,也可能一个集群实现。
  • 信息交换层(Exchange):封装请求响应模式,同步转异步,以Request和Response为中心,扩展接口为Exchanger、ExchangeChannel、ExchangeClient和ExchangeServer。
  • 网络传输层(Transport):抽象mina和netty为统一接口,以Message为中心,扩展接口为Channel、Transporter、Client、Server和Codec。
  • 数据序列化层(Serialize):可复用的一些工具,扩展接口为Serialization、 ObjectInput、ObjectOutput和ThreadPool。

根据官方提供的,对于上述各层之间关系的描述,如下所示:

  • 在RPC中,Protocol是核心层,也就是只要有Protocol + Invoker + Exporter就可以完成非透明的RPC调用,然后在Invoker的主过程上Filter拦截点。
  • 图中的Consumer和Provider是抽象概念,只是想让看图者更直观的了解哪些类分属于客户端与服务器端,不用Client和Server的原因是Dubbo在很多场景下都使用Provider、Consumer、Registry、Monitor划分逻辑拓普节点,保持统一概念。
  • 而Cluster是外围概念,所以Cluster的目的是将多个Invoker伪装成一个Invoker,这样其它人只要关注Protocol层Invoker即可,加上Cluster或者去掉Cluster对其它层都不会造成影响,因为只有一个提供者时,是不需要Cluster的。
  • Proxy层封装了所有接口的透明化代理,而在其它层都以Invoker为中心,只有到了暴露给用户使用时,才用Proxy将Invoker转成接口,或将接口实现转成Invoker,也就是去掉Proxy层RPC是可以Run的,只是不那么透明,不那么看起来像调本地服务一样调远程服务。
  • 而Remoting实现是Dubbo协议的实现,如果你选择RMI协议,整个Remoting都不会用上,Remoting内部再划为Transport传输层和Exchange信息交换层,Transport层只负责单向消息传输,是对Mina、Netty、Grizzly的抽象,它也可以扩展UDP传输,而Exchange层是在传输层之上封装了Request-Response语义。
  • Registry和Monitor实际上不算一层,而是一个独立的节点,只是为了全局概览,用层的方式画在一起

2.3、dubbo服务调用流程

服务提供方与服务消费放之间调用关系:

9795603-43d8dbc3bb93352f.png
调用关系.png

上图中,蓝色的表示与业务有交互,绿色的表示只对Dubbo内部交互。上述图所描述的调用流程如下:

  • 服务提供方发布服务到服务注册中心;
  • 服务消费方从服务注册中心订阅服务;
  • 服务消费方调用已经注册的可用服务

将上面抽象的调用流程图展开,详细如图所示:

9795603-8ea2623b81823e96.png
抽象流程图.png

注册/注销服务:
服务的注册与注销,是对服务提供方角色而言,那么注册服务与注销服务的时序图,如图所示:

9795603-e4288fd42594ede6.png
注册注销流程.png

服务订阅/取消:
为了满足应用系统的需求,服务消费方的可能需要从服务注册中心订阅指定的有服务提供方发布的服务,在得到通知可以使用服务时,就可以直接调用服务。反过来,如果不需要某一个服务了,可以取消该服务。下面看一下对应的时序图,如图所示:

9795603-a13c31e388f9fc76.png
订阅取消流程.png

2.4、dubbo架构有以下特点

连通性:

  • 注册中心负责服务地址的注册与查找,相当于目录服务,服务提供者和消费者只在启动时与注册中心交互,注册中心不转发请求,压力较小
  • 监控中心负责统计各服务调用次数,调用时间等,统计先在内存汇总后每分钟一次发送到监控中心服务器,并以报表展示
  • 服务提供者向注册中心注册其提供的服务,并汇报调用时间到监控中心,此时间不包含网络开销
  • 服务消费者向注册中心获取服务提供者地址列表,并根据负载算法直接调用提供者,同时汇报调用时间到监控中心,此时间包含网络开销
  • 注册中心,服务提供者,服务消费者三者之间均为长连接,监控中心除外
  • 注册中心通过长连接感知服务提供者的存在,服务提供者宕机,注册中心将立即推送事件通知消费者
  • 注册中心和监控中心全部宕机,不影响已运行的提供者和消费者,消费者在本地缓存了提供者列表
  • 注册中心和监控中心都是可选的,服务消费者可以直连服务提供者

健壮性:

  • 监控中心宕掉不影响使用,只是丢失部分采样数据
  • 数据库宕掉后,注册中心仍能通过缓存提供服务列表查询,但不能注册新服务
  • 注册中心对等集群,任意一台宕掉后,将自动切换到另一台
  • 注册中心全部宕掉后,服务提供者和服务消费者仍能通过本地缓存通讯
  • 服务提供者无状态,任意一台宕掉后,不影响使用
  • 服务提供者全部宕掉后,服务消费者应用将无法使用,并无限次重连等待服务提供者恢复

伸缩性:

  • 注册中心为对等集群,可动态增加机器部署实例,所有客户端将自动发现新的注册中心
  • 服务提供者无状态,可动态增加机器部署实例,注册中心将推送新的服务提供者信息给消费者

升级性:

当服务集群规模进一步扩大,带动IT治理结构进一步升级,需要实现动态部署,进行流动计算,现有分布式服务架构不会带来阻力。下图是未来可能的一种架构:


9795603-47a12b419b65a87b.png
未来架构.png

3、其他说明

3.1、协议支持

Dubbo支持多种协议,如下所示:

  • Dubbo协议
  • Hessian协议
  • HTTP协议
  • RMI协议
  • WebService协议
  • Thrift协议
  • Memcached协议
  • Redis协议

在通信过程中,不同的服务等级一般对应着不同的服务质量,那么选择合适的协议便是一件非常重要的事情。你可以根据你应用的创建来选择。例如,使用RMI协议,一般会受到防火墙的限制,所以对于外部与内部进行通信的场景,就不要使用RMI协议,而是基于HTTP协议或者Hessian协议。

3.2、dubbo模块结构及关系

9795603-f234b27ffb27cc6a.png
dubbo模块结构.png

可以通过Dubbo的代码(使用Maven管理)组织,与上面的模块进行比较。

简单说明各个包的情况:

  • dubbo-common:公共逻辑模块,包括Util类和通用模型。
  • dubbo-remoting:远程通讯模块,相当于Dubbo协议的实现,如果RPC用RMI协议则不需要使用此包。
  • dubbo-rpc:远程调用模块,抽象各种协议,以及动态代理,只包含一对一的调用,不关心集群的管理。
  • dubbo-cluster:集群模块,将多个服务提供方伪装为一个提供方,包括:负载均衡、容错、路由等,集群的地址列表可以是静态配置的,也可以是由注册中心下发。
  • dubbo-registry:注册中心模块,基于注册中心下发地址的集群方式,以及对各种注册中心的抽象。
  • dubbo-monitor:监控模块,统计服务调用次数,调用时间的,调用链跟踪的服务。
  • dubbo-config:配置模块,是Dubbo对外的API,用户通过Config使用Dubbo,隐藏Dubbo所有细节。
  • dubbo-container:容器模块,是一个Standalone的容器,以简单的Main加载Spring启动,因为服务通常不需要Tomcat/JBoss等Web容器的特性,没必要用Web容器去加载服务。

3.3、参考文档

参考博客:
http://shiyanjun.cn/archives/325.html
https://www.cnblogs.com/aspirant/p/9002663.html
https://github.com/apache/incubator-dubbo
http://alibaba.github.io/dubbo-doc-static/FAQ-zh.htm

猜你喜欢

转载自blog.csdn.net/weixin_34187862/article/details/87017605