Dubbo的架构与调用流程详解

前言

本文主要对 Dubbo 的简介,架构等宏观方面对 Dubbo 进行介绍。

应用架构的演进

单体应用

早期的应用架构是大多是单体应用,随着互联网的快速发展以及数据量的急剧增长和业务的复杂度,很多企业会对应用进行垂直拆分,即把业务上没有关联的系统独立拆分出来,形成独立对外提供服务的系统。此时,服务之间完全独立,无法进行远程调用,很多基础代码不能复用,需要复制使用。为了解决这些存在的问题,衍生出了分布式应用。

分布式应用

SOA架构

为了解决单体应用出现的问题,面向服务的架构(SOA)出现了,SOA 将单一进程的应用做了拆分,形成独立对外提供服务的组件,每个组件通过网络协议对外提供服务。网络协议可以是TCP,也可以是 Http等,通过这种协议,服务之间可以通过接口进行交互。SOA有以下特点:

  • 明确的协议,服务间的交互通过特定的协议进行
  • 明确的接口,每个服务有明确的对外接口,让服务可以复用
  • 合作方式的改变,有了更加细化的分工与合作方式
  • 通信方式,初期通信方式通常为 XML,后来被 Json 取代

SOA 的实现方式有两种:Web Service 和 ESB,但这两种方式的缺点都显而易见,Web Service 的通信协议笨重,服务化管理设置不完善;ESB 本身就很重,系统的变更可能又反过来影响总线的变更。

微服务化

为了解决SOA中存在的各种问题,近几年的服务化架构得到了进一步演进,主键形成了更加细粒度的微服务架构,在微服务架构中,一个服务被拆分成一个个独立、可配置、可运行、可维护的子服务,极大的方便了服务的复用,通过不同的服务编排方式,快速产生新的业务逻辑。

Dubbo

在分布式场景下,很重要的分布式通信问题的解决方案之一就是 Dubbo,编写分布式场景下高并发、高可扩展的系统对技能的要求很高,因为其中涉及序列化/反序列化、网络、多线程、设计模式、性能优化等众多知识,Dubbo 可以很好的将这些做更高层的抽象和封装,提供了各种开箱即用的特性,让用户傻瓜式的使用。

架构

上图为Dubbo的架构,流程如下:

  • 服务的Container负责启动,加载并运行 Provider
  • Provider 在启动时会向注册中心把自己的元数据注册上去(服务Ip,Port等)
  • Consumer 启动时向注册中心订阅服务提供方的元数据
  • 注册中心将服务提供者地址列表给消费者,如发生数据变更会推送给订阅的 Consumer
  • 在获取元数据后,Consumer 可以发起 RPC 调用
  • 在 RPC 调用前后会向监控中心上报统计信息(并发数,调用接口等)

Dubbo解决的问题:

1、高性能、透明的RPC调用

2、服务的自动注册与发现

  • 自动负载与容错
  • 动态流量调度
  • 依赖分析与调用统计

分层

Dubbo的实现采用分层的思想,每层负责不同的职责,让用户可以基于Dubbo框架做二次开发,扩展其功能。Dubbo的扩展能力非常强,这也是Dubbo广受欢迎的原因。

Dubbo总体分为三层:业务层(Biz),RPC层,Remote层。如果把每一层细分,可以分为十层。

image.png

Dubbo框架中的分层代表了不同的逻辑实现,它们是一个个组件,组件构成了整个Dubbo体系,下面是Dubbo的核心组件。

image.png

总体调用过程

服务的暴露过程:

首先,服务器端(服务提供者)在框架启动时,会初始化服务实例,通过 Proxy 组件调用具体协议,把服务端要暴露的接口封装成Invoker (真实类型是AbstractProxyInvoker),然后转换成Exporter,这个时候框架会打开服务端口等并记录服务实例到内存中,最后通过Registry 把服务元数据注册到注册中心。这就是服务端(服务提供者)整个接口暴露的过程。

image.png

首先,调用过程也是从一个Proxy开始的,Proxy持有了一个Invoker对象。然后触发invoke调用。在invoke调用过程中,需要使用Cluster,Cluster 负责容错,如调用失败的重试。Cluster 在调用之前会通过 Directory获取所有可以调用的远程服务Invoker列表(一个接口可能有多个节点提供服务)。由于可以调用的远程服务有很多,此时如果用户配置了路由规则(如指定某些方法只能调用某个节点),那么还会根据路由规则将Invoker列表过滤一遍。

然后,存活下来的Invoker可能还会有很多,此时要调用哪一个呢?于是会继续通过LoadBalance方法做负载均衡,最终选出一个可以调用的Invoker。这个Invoker在调用之前又会经过一个过滤器链,这个过滤器链通常是处理上下文、限流、计数等。 接着,会使用Client做数据传输,如我们常见的Netty Client 等。传输之前肯定要做一些私有协议的构造,此时就会用到Codec接口。构造完成后,就对数据包做序列化(Serialization),然后传输到服务提供者端。服务提供者收到数据包,也会使用Codec处理协议头及一些半包、粘包等。处理完成后再对完整的数据报文做反序列化处理。

随后,这个Request会被分配到线程池(ThreadPool)中进行处理。Server 会处理这些Request,根据请求查找对应的Exporter(它内部持有了Invoker)。Invoker是被用装饰器模式一层一层套 了非常多Filter的,因此在调用最终的实现类之前,又会经过一个服务提供者端的过滤器链。

最终,得到了具体接口的真实实现并调用,再原路把结果返回。到此,一个完整的远程调用过程就结束了。

小结

本文介绍了应用架构的演进过程,还包括Dubbo的架构,分层,总体调用过程等。如对 Dubbo 感兴趣可继续关注本专栏。

  • 38
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值