最近我拜读了mindwind的一片博客文章深入浅出 RPC - 深入篇,希望通过Dubbo深入学习RPC架构设计,在此结合RPC架构的原理,解析Dubbo是如何实现RPC架构的。

RPC架构模型

RPC架构的主要目的是在构建分布式系统时,调用远程方法就如同调用本地方法一样方便快捷,简化开发,提高效率。

我们看看下面这张图,了解一下RPC架构的主要组成部分及调用关系:

以上图片引自mindfloating的博客

上图左侧是调用者,右侧是方法提供端。我们分别解释一下上图的各模块的职责:

从左侧开始,Caller是调用者;RpcClient是Rpc协议定义的客户端,包括远程接口的地址列表及调用方式的信息等,Caller导入RpcClient;RemoteAPI表示远程接口;RpcProxy是一个对远程方法调用的代理组件,封装了远程过程调用的细节,可以包括加载地址列表,寻址,调用集群模块实现负载均衡、高可用,查找调用信息,调用RpcInvoker等;RpcInvoker是具体的RemoteAPI的调用者封装对象,它包含了一个具体接口方法的地址、调用方式等信息,并提供了调用处理方法;RpcConnector负责封装实现网络通信细节,如建立会话通道,发送数据请求和接收返回值数据;RpcProtocol是Rpc协议规范,定义了数据序列化和反序列化方法,如何解析地址信息等细节。

右侧为接口服务端,RpcAcceptor类似RpcConnector,封装实现网络通信细节,接收请求数据,发送本地接口处理后的返回值给客户端;RpcProcessor负责线程池管理,发起本地方法调用等;服务端RpcInvoker是本地API的调用者,通过反射技术调用指定接口的方法;Callee是服务端的本地接口类,导出RPC服务为RpcServer,客户端Caller将其作为RpcClient导入.

我们按照以上RPC的调用流程和各组件职责,聊一聊Dubbo是如何实现的。

Dubbo的RPC架构实现

Dubbo的调用关系如下图所示,以注册中心Registry为中心,Provider即服务提供者,将服务export出来注册(1、register)存储到Registry,Consumer即客户端调用者,从Registry订阅所关心的服务(2、subscribe),首次订阅时拉取订阅服务所有的地址列表(服务提供者注册到Registry上的信息),当订阅服务有更新(地址变更或有新的地址注册加入),Consumer收到注册中心的服务更新通知(3、notify),以上是服务端export的过程。

客户端发起RPC调用时,首先从服务地址列表里refer()指定的服务,这其中有服务寻址和从集群中筛选最终指向一个服务的过程,这就是import的过程。得到某个服务指向,则发起远程调用(4、invoke)。

以上图片引自Dubbo官方用户手册

那么Dubbo具体是如何实现RPC的整个过程的呢?对应RPC模型,Dubbo相应的组件又是如何实现和交互的?下图展示了Dubbo整个设计思路。

以上图片引自Dubbo官方用户手册

图例说明:

  • 图中左边淡蓝背景的为服务消费方使用的接口,右边淡绿色背景的为服务提供方使用的接口,位于中轴线上的为双方都用到的接口。
  • 图中从下至上分为十层,各层均为单向依赖,右边的黑色箭头代表层之间的依赖关系,每一层都可以剥离上层被复用,其中,Service 和 Config 层为 API,其它各层均为 SPI。
  • 图中绿色小块的为扩展接口,蓝色小块为实现类,图中只显示用于关联各层的实现类。
  • 图中蓝色虚线为初始化过程,即启动时组装链,红色实线为方法调用过程,即运行时调时链,紫色三角箭头为继承,可以把子类看作父类的同一个节点,线上的文字为调用的方法。

接下来我们对应RPC架构模型的组件谈谈Dubbo的设计。

export和import

Dubbo服务端接口export(导出)是将接口信息注册到注册中心Registry的过程。而客户端import(导入)远程接口是通过从注册中心Registry订阅远程服务接口,收到通知后拉取到本地的过程。
注册和订阅的过程,不需要修改服务端本地的类和方法,只需保证客户端和服务端共同引用一个包含接口的jar包。服务端和客户端分别编写简单的dubbo接口配置xml文件(或注解的方式),容器启动时就自动注册和订阅了。

客户端调用的过程

看上图Config层的橙色小圆点,红色实线剪头为调用链。客户端invoke远程API(Interface),实际是调用了Proxy层的RpcProxy,proxy又调用集群组件Cluster,从集群中筛选出一个Invoker作为调用者发起调用。

我们看到,在Cluster层中筛选的过程调用了Directory(实现类为RegistryDirectory)、Router、LoadBalance,分别通过Directory实现了服务的高可用,通过Router实现了智能路由功能,通过LoadBalance实现了负载均衡。

从集群模块中筛选出一个Invoker后执行invoke()方法执行方法调用,到了Protocol协议层,经过Filter组件做拦截过滤处理,如用户名、密码验证等可在此处理。过滤通过后,调用Protocol实现类如DubboProtocol或HessianProtocol等的invoke()方法。

具体的协议实现类(如DubboProtocol)会请求ExchangeClient组件,它封装了具体的数据通讯细节,是底层数据通信的代理层。因此它自然会调用底层的通信组件(默认是Netty)实现Client建立连接、Server绑定端口和数据传输(request、return)的功能。

数据传输前需要数据序列化,服务端接收到数据需要反序列化,这些都靠序列化组件实现。Codec是序列化组件的代理层,具体序列化协议,默认是Hessian,还可选择Kryo,Thrift(被Dubbo改造,与原Thrift不兼容),dubbo, hessian2, java, json等,具体参见Dubbo用户手册

服务端调用

服务端接收到客户端的请求后,反序列化数据,通过DubboHandler协议处理请求,找到注册的本地Exporter,触发invoke(),经过过滤器处理后,调用Invoker代理层,触发真正的本地接口调用,返回数据序列化后发送给客户端。

以上内容以RPC模型为基础,分析总结了Dubbo实现RPC的大体流程,后续我还会分别针对某些组件展开讨论Dubbo的设计实现。

Dubbo架构深入篇----RPC实现总结的更多相关文章

  1. 远程服务调用RPC框架介绍,微服务架构介绍和RPC框架对比,dubbo、SpringClound对比

    远程服务调用RPC框架介绍,微服务架构介绍和RPC框架对比,dubbo.SpringClound对比 远程服务调用RPC框架介绍,RPC简单的来说就是像调用本地服务一样调用远程服务. 分布式RPC需要 ...

  2. Dubbo架构设计详解-转

    Dubbo架构设计详解  2013-09-03 21:26:59    Yanjun Dubbo是Alibaba开源的分布式服务框架,它最大的特点是按照分层的方式来架构,使用这种方式可以使各个层之间解 ...

  3. 微服务架构介绍和RPC框架对比

    微服务架构介绍和RPC框架对比 1.微服务架构 1.1 特征 自动化部署,端点智能化,语言和数据的去中心化控制. 1.2架构 一种将一个单一应用程序开发为一组小型服务的方法,每个服务运行在自己的进程中 ...

  4. dubbo系列一:dubbo介绍、dubbo架构、dubbo的官网入门使用demo

    一.dubbo介绍 Dubbo是阿里巴巴公司开源的一个高性能优秀的服务框架,使得应用可通过高性能的RPC实现服务的输出和输入功能,可以和Spring框架无缝集成.简单地说,dubbo是一个基于Spri ...

  5. 深入浅出微服务框架dubbo(一):基础篇

    一.基础篇 1.1 开篇说明 dubbo是一个分布式服务框架,致力于提供高性能透明化RPC远程调用方案,提供SOA服务治理解决方案.本文旨在将对dubbo的使用和学习总结起来,深入源码探究原理,以备今 ...

  6. Dubbo API 笔记——Dubbo架构与使用

    转载于: https://blog.csdn.net/benhuo931115/article/details/78457149 架构演变 单一应用架构 所有功能部署在一个应用上,用于简化增删改查工作 ...

  7. Dubbo+Zookeeper(二)Dubbo架构

    上次更新博客已经是一年前,这一年发生了很多事,并不顺利,甚至有些痛苦,不过不管怎样,不要停止学习,只有学习才能让你变强,应对更多不安定. 一.RPC概念 Dubbo服务是一个RPC框架,那我们首先就要 ...

  8. 基于dubbo框架下的RPC通讯协议性能测试

    一.前言 Dubbo RPC服务框架支持丰富的传输协议.序列化方式等通讯相关的配置和扩展.dubbo执行一次RPC请求的过程大致如下:消费者(Consumer)向注册中心(Registry)执行RPC ...

  9. VS2010+MVC4+Spring.NET2+NHibernate4-传统三层架构-前篇

    VS2010+MVC4+Spring.NET2+NHibernate4 - 传统三层架构 - 前篇 一直追求使用开源项目,就因一个字:懒! 一直想整理一下的,却一直懒到现在!从当初用的MVC3到现在的 ...

随机推荐

  1. AOP代理

  2. ASP.NET的OnClientClick与OnClick事件

    OnClientClick是客户端事件方法.一般采用JavaScript来进行处理.也就是直接在IE端运行.一点击就运行. OnClick事件是服务器端事件处理方法,在服务器端,也就是IIS中运行.点 ...

  3. HDU 2037(贪心)

    “今年暑假不AC?” “是的.” “那你干什么呢?” “看世界杯呀,笨蛋!” “@#$%^&*%...” 确实如此,世界杯来了,球迷的节日也来了,估计很多ACMer也会抛开电脑,奔向电视了.  ...

  4. HDU 1276 士兵队列训练问题(模拟)

    原题代号:HDU 1276 原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=1276 题目原题: 士兵队列训练问题 Time Limit: 2000/10 ...

  5. 手把手教你做echarts图表系列之组织结构图

    在实际项目中使用echarts越来越多了,今天从一个组织结构图开始,手把手教大家开发echarts图表. 公司里的组织结构图如下: 可以参考echarts入门教程:http://echarts.bai ...

  6. 从Java 调用JavaScript

    篇幅过长 下载资源链接https://www.slidestalk.com/s/java_javascript_5hl09w

  7. 2018-2019-2 20175214 实验四《Android程序设计》实验报告

    实验四<Android程序设计>实验报告 一.前期准备 安装Android Studio 参考http://www.cnblogs.com/rocedu/p/6371315.html#SE ...

  8. scrapy Pipeline使用twisted异步实现mysql数据插入

    from twisted.enterprise import adbapi class MySQLAsyncPipeline: def open_spider(self, spider): db = ...

  9. oracle 11g不能导出空表的解决方法

    在oracle 11g r2中,发现传统的exp居然不能导出空的表,然后查询一下,  发现需要如下的步骤去搞,笔记之.    oracle 11g 新增了一个参数:deferred_segment_c ...

  10. Delphi XE2 之 FireMonkey 入门(16) - 滤镜: 实例测试

    窗体上需要 TImage.TOpenDialog 和六个按钮. unit Unit1; interface uses   System.SysUtils, System.Types, System.U ...