前端也能懂的RPC(中)——一次RPC调用

上一篇:前端也能懂的RPC(上)

这一节解释,在RPC调用中到底发生了什么。



由于我用的RPC框架是HSF,其他的RPC框架也一样,都大同小异了,看架构图再思考RPC更容易理解一些。如下:

HSF架构

HSF作为一个纯客户端架构的RPC框架,没有服务端集群,所有HSF服务调用均是通过服务消费方(Consumer)与服务提供方(Provider)点对点进行。为了实现整套分布式服务体系,HSF还需要依赖以下外部系统。


一、以传输对象为视角的调用流程

一次调用

1、动态代理

上一节讲到,在midway项目中调用hsf服务,其实就是调用hsfClient.createConsumer.consumer.invoke.call......
这个代理的作用是屏蔽调用细节,让使用者调用hsf服务时,拥有像调用本地已有调用远程的体验。

2、序列化

序列化 (Serialization)是将对象的状态信息转换为可以存储或传输的形式的过程。

上节提到,数据在网络中以二进制的形式进行传输,那么在RPC的调用里,数据是怎么从一个对象变成二进制数据的呢?

入参对象到RPC数据包

a. 序列化格式

前端最熟悉的格式就是JSON了,除了JSON之外,服务端的序列化格式还有Hessian、Protobuf等等。这里以JSON为例讲解。

b. 序列化流程

  • 假设我们有一个入参对象
{
  id: 123,
  name: "apple",
  arr: [1,2,3,'b']
}

这个对象不是一个标准的json对象,先把它序列化成标准的JSON对象

  • JSON
{
  id: 123,
  name: "apple",
  arr: ["1","2","3","b"]
}
  • 以某种编码方式将其转换成二进制数据

  • IO线程
    二进制数据将会经过TCP传输给服务提供方,服务提供方从TCP通道里收到二进制数据。
    这个转变成二进制数据从而封装成TCP包传输的工作发生在IO线程中。

  • 额外的信息
    有了二进制数据,还需要知道调用的方法名;
    为了让接收方能够反序列化成功,需要传输序列化方式;
    二进制数据过大时,需要分包,那么需要字段用以描述包序号;
    为了确保数据完整性,需要整体长度……
    那么这些信息应该怎么样去放置呢?

使用协议来把上述提到的协议体和协议头内容通过一定的方式组合在一起。

  • 协议

协议的作用就是用于分割二进制数据流。

可以使用现有的协议,如HTTP2.0协议,或者自己设计一个协议


协议

至此,一个入参对象就成功转变成了可以在网络间传输的RPC数据包

3、网络通信——IO多路复用

网络通信是整个RPC调用的基础,选择哪种网络IO模型更适合这个场景呢?

IO 密集型系统大部分时间都在执行 IO 操作,这个 IO 操作主要包括网络 IO 和磁盘 IO,以及与计算机连接的一些外围设备的访问。
我们开发的绝大多数业务系统,都是IO密集型系统,很少有非常耗时的计算,更多的是网络收发数据,读写磁盘和数据库这些 IO 操作。这样的系统基本上都是 IO 密集型系统,特别适合使用异步的设计来提升系统性能。

  • 复习一下node TCP发送请求
var net = require('net');
var tcp_server = net.createServer();  // 创建 tcp server

var Sockets = {};
var SocketID = 1;

// 监听 端口
tcp_server.listen(8888,function (){
    console.log('tcp_server listening 8888');
});

// 处理客户端连接
tcp_server.on('connection',function (socket){
    console.log(socket.address());
    Sockets[SocketID] =socket;
    SocketID++;
    DealConnect(socket)
})

tcp_server.on('error', function (){
    console.log('tcp_server error!');
})

tcp_server.on('close', function () {
    console.log('tcp_server close!');
})


// 处理每个客户端消息
function DealConnect(socket){

    socket.on('data',function(data){
        data = data.toString();
        // 向所有客户端广播消息
       for(var i in Sockets){
           Sockets[i].write(data);
       }
        // socket.write(data);
        console.log('received data %s',data);
    })

    // 客户端正常断开时执行
    socket.on('close', function () {
        console.log('client disconneted!');
    })
// 客户端正异断开时执行
    socket.on("error", function (err) {
        console.log('client error disconneted!');
    });
}

上面代码使用server.listen去监听端口8888,这个端口就是一个通道。如果有请求接收过来,则执行传入'connect'的回调函数。使用 socket.write往通道写数据传回去。

一个 TCP 连接建立后,用户代码会获得一个用于收发数据的通道,每个通道会在内存中开辟两片区域用于收发数据的缓存。

同步阻塞IO


同步阻塞IO就是应用进程发起IO系统调用后,应用进程被阻塞直到等待到数据,经过操作系统通知,从缓存拿到接收来的数据拷贝到用户内存,然后接触阻塞状态,运行业务逻辑。
这样一来,每一个IO操作都要占用线程,直到IO操作结束。
如果有大量的请求涌入,那些等待着的IO线程因为阻塞不能及时处理,就是极大的资源浪费了。

IO多路复用

因为同步阻塞IO对于高并发场景并不适用,IO多路复用是怎么解决这个场景的?
相较于同步阻塞IO,IO多路复用就是将多个通道复用在一个复用器上,接收到任意一个数据后,线程会将这个数据从缓存拷到内存中处理,处理完成后线程再重新回到等待状态。这样一个线程就能处理多个socket了。

参考:
1、https://help.aliyun.com/document_detail/149498.html?spm=5176.22414175.sslink.1.5c6c4515nPbJT9
2、https://time.geekbang.org/column/article/118322
3、https://time.geekbang.org/column/article/204696
4、https://www.cnblogs.com/ay-a/p/9822057.html

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

推荐阅读更多精彩内容