第02篇 远程调用的过程

在上一个章节,我们了解到为什么要使用远程调用,以及在远程调用过程中所经历的步骤。下面我们就以小蓝和小红的对话为例,详细来讲一下为什么一次调用的过程会经过这么多的步骤,以及它们的作用与意义。

首先我们想一下,小蓝和小红如何通过网络进行对话呢?回想学过的知识,我们可以使用 Socket 建立一个 TCP 连接,然后他们两人就可以通过 Socket 来收发通话信息了,就像下面这样:

1)传输层的作用

不过这里有一个问题,数据在网络中是以二进制流的方式持续传输的,那如何分清楚一条消息数据的开始和结束呢?比如像下面这样,“小蓝”连续对“小红”说了三科成绩(这就相当于连续进行了三次 RPC 调用),这种情况下“小红”是搞不清楚他在说什么的:

所以这里我们要引入一个被称为“传输层”的东西。这样在数据发送出去前,我们先将数据交给“传输层”,由“传输层”对每一次要发送的数据进行封装,然后再通过 Socket 发送出去。如此以来我们就可以解决上面的问题。

那么“传输层”要将数据封装成什么样子呢?比如,我们可以将数据封装成下图这种样子,在数据前加上一个 4 个字节长度的内容,用来表示数据的长度。这样“小红”接收到数据后,读取前 4 个字节就能知道本次数据的长度,然后再继续读取对应长度的数据就得到了本次传输内容。而超过这个长度后如果还有数据,则为下一次请求中的数据。

通过“传输层”解析一次调用的完整数据

2)协议层的作用

上面我们通过“传输层”封装了每次调用的数据,目的是确保接收方可以正确的取出对应数据(不会多或少于发送的数据)。

而现在我们又发现一个问题,就是传输的数据有可能会比较复杂,可能是一个复杂的数据对象或者复杂的集合类型,但是我们通过网络传输时,传输的内容是字节流。所以我们必须得想办法,把这个复杂的数据对象或集合转换成字节流,然后才能交给“传输层”装帧发送出去。

比如下面就是一个复杂的参数,它是一个我们自定义的类,有两个字段。这个时候我们就要想办法将这个对象中的数据,序列化成字节流的形式,再交给传输层去传输。

public class Solve {
    int seq = 1;
    String opt = "A";
}

所以这时我们可以加入“协议层”去做这个事情,通过“协议层”将复杂的数据转换成字节流,再经过“传输层”封装后,就可以交给 Socket 发送出去了。

那么“协议层”是怎么做的呢?本质上“协议层”是从对象的各个属性中取出来数据,按“某种规则”拼接成了字节数组。而这里的“某种规则”可以是“JSON”,那么也就是说我们可以将对象数据转换成 JSON 样式的字符串,再从字符串转化为字节数组。下面就是将对象中的转换成 JSON 样式字符串的效果。

{"seq":1,"opt":"A"}

这样通过引入“协议层”我们就解决了复杂数据的传输问题。有了上述的两层后,我们的 RPC 就基本可用了。每次想通过 RPC 调用对方时,先使用“协议层”将参数序列化,然后再使用“传输层”在数据的最前面加上长度信息并发送出去。

通过“协议层”将数据序转换成二进制字节流

3)处理器的作用

上面我们说有了“协议层”和“传输层”后就基本可用了,为什么是基本可用呢?是因为上述过程只适用于被调方是单个方法的情况,这样接收到参数后,去执行这个方法就行。但实际我们肯定不止一个方法,如果我们只发送参数信息过去,那谁能知道你需要调用哪个方法呢?

所以我们要把方法名称也一起发送给被调用方,这样调用方就能区分出来调用的是哪个方法。调用方根据方法名称去匹配到对应的方法,并执行调用。而去做这件事情的代码我们将其称为“处理器”,也就是说由“处理器”来选择要目标方法并进行调用。

如下图中我们就已经添加上了“处理器”,这样由“处理器”拿到本次请求的方法名称后,寻找到对应的要执行的方法,调用并将参数传入,等方法执行完成再将结果返回交给协议层封装处理。

通过“处理器”去匹配到对应的方法并执行

4)客户端代理类

另外,加上上述这么多的层次后,整个 RPC 调用过程就变得复杂了起来,如果我们每次写 RPC 功能时都要去这么多逻辑,那就太繁琐了。而前面我们也说过,RPC 框架的作用就是让我们在调用远程方法时,能够像调用本地方法一样简便,那 RPC 框架是怎么做到这一点的呢?

为了能让我们使用 RPC 时能和本地方法一样,不需要关注内部这些数据转化和传输的繁琐过程,我们再引入一个“代理”的概念。即 RPC 框架在客户端根据接口生成一个“接口代理类”,然后客户端直接调用该接口代理类即可。在代理中我们获取方法中传来的参数,并将参数和方法信息通过协议层序列化,再通过传输层发送出去。

5)编解码器

我们可以为每个接口类都定制化的生成一个接口代理类,专门为这个接口服务,但是这样做代码冗余太多,接口一旦有改动就要关联的去修改代理类,并不是很方便。所以接口的代理类一般都是一段通用的代码,能够代理任何接口。

但既然代理类是通用的代码,那么就要考虑如何将参数读取出来,再通过协议层序列化呢?因为通用的代码我们无法直接通过参数 get 方法获取值,这时候我们想起来 gson 或 fastjson 等 JSON 格式转换工具,通过它们就可以将参数数据直接转换成 JSON 格式的数据,而它们本质上是通过反射处理的这一切。同样 Thrift 也提供了通过反射机制读取参数数据的工具,就是编解码器。Thrift 解析接口及参数,生成对应的编解码器,通过编解码器与协议层的配合使用,Thrift 就能将参数数据序列化了。

增加接口代理和编解码器后,使得 RPC 框架整体的使用舒适度上大大提升,使用 RPC 调用时只需和普通调用一样调用接口方法即可,后面的工作全都由代理类去处理。

6)服务管理与模型

客户端通过代理类屏蔽了 RPC 调用过程中的细节,而服务我们也加上一层服务类,也屏蔽掉服务端处理 RPC 调用过程的细节,让我们在开发 RPC 的服务端时不需要考虑太多,只需要实现接口对应的业务逻辑即可。这样服务类需要做的就是去请求数据、反序列化数据,再通过编解码器将数据组装成参数由处理器匹配到目标方法执行调用。

这样以来,我们就得了完整的 RPC 结构模型,

以上就是 RPC 框架的层次结构,通过上述描述大家应该能了解到各个层次的存在的意义以及用途。下一章我们就来看一下如何使用 Thrift 这个 RPC 框架进行开发。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
禁止转载,如需转载请通过简信或评论联系作者。
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,921评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,635评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,393评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,836评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,833评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,685评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,043评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,694评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,671评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,670评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,779评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,424评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,027评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,984评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,214评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,108评论 2 351
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,517评论 2 343

推荐阅读更多精彩内容