最近我拜读了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. NPM错误

    有时突然报下面错误: 本人经验是IP变了...

  2. #431 Div2 Problem B Tell Your World (鸽巢原理 && 思维)

    链接 : http://codeforces.com/contest/849/problem/B 题意 : 给出 n 个在直角坐标系上的点,每个点的横坐标的值对应给出的顺序序数,比如 1 2 4 3 ...

  3. PS4 Submission

    第一部分是param.sfo文件的设置: 另外,sce_sys目录下的icon0.png文件和pic1.png文件也可以手动修改成自己需要的样式,前者是在游戏中的logo,图片要求是512x512,p ...

  4. 大数据学习第二章、HDFS相关概念

    1.HDFS核心概念: 块 (1)为了分摊磁盘读写开销也就是大量数据间分摊磁盘寻址开销 (2)HDFS块比普通的文件块大很多,HDFS默认块大小为64MB,普通的只有几千kb 原因:1.支持面向大规模 ...

  5. 170816-关于Java基础的习题

    1. switch 括号里的可以是 int .char. byte.short.String,还有枚举类型,应用举例 不可以是long.double 2. 调用ma()方法之后,ma()方法将错误类型 ...

  6. 解决Acunetix 12中文汉化的方法

    最近下载一款测试软件acunetix,苦于满屏英文的苦恼,看不懂,于是乎就问度娘,结果度娘就是给中文破解包: 我是12版的,网上提供的都是11版的,没法用.怎么办呢?还好我是做测试的,平时做兼容性测试 ...

  7. qbzt day6 下午 模拟赛

    我太菜了 T2 给定一张有向图,每个点有点权.试找到一条路径,使得该路径上的点权最 大值减去点权最小值最大,问这个差最大是多少.   话说这个题第一个想到的思路是tarjan缩点+拓扑排序来着... ...

  8. 模拟赛DAY1 T2腐草为萤

    2.腐草为萤(dzy.cpp/c) [题目背景] 纤弱的淤泥中妖冶颓废在季夏第三月最幼嫩的新叶连凋零都不屑何必生离死别——银临<腐草为萤> [问题描述] 扶苏给了你一棵树,这棵树上长满了幼 ...

  9. 从数据库、页面加载速度角度思考 id设计 sku asin

    (已对数据进行字符串替换,去身份识别.隐私跟踪) 12-13-14-15-16-18岁20女孩夏装初中高中学生韩版上衣服短袖T恤衫-tmall.com天猫 https://detail.tmall.c ...

  10. ContentProvider,ContentResolver和ContentObserver 使用

    1 ContentProvider内容提供者 四大组件之一,实现不同程序实现数据的共享.联系人应用就使用了ContentProvider,比如你在自己的应用可以读取和修改联系人的数据(获得相应权限). ...