深入理解 RPC 交互流程

文节我们讲解 RPC 的消息交互流程,目的是搞清楚一个简单的 RPC 方法调用背后究竟发生了怎样复杂曲折的故事,以看透 RPC 的本质。

上图是信息系统交互模型宏观示意图,RPC 的消息交互则会深入到底层。

RPC 是两个子系统之间进行的直接消息交互,它使用操作系统提供的套接字来作为消息的载体,以特定的消息格式来定义消息内容和边界。

RPC 的客户端通过文件描述符的读写 API (read & write) 来访问操作系统内核中的网络模块为当前套接字分配的发送 (send buffer) 和接收 (recv buffer) 缓存。

如上图所示,左边的客户端进程写 RPC 指令消息到内核的发送缓存中,内核将发送缓存中的数据传送到物理硬件 NIC,也就是网络接口芯片 (Network Interface Circuit)。NIC 负责将翻译出来的模拟信号通过网络硬件传递到服务器硬件的 NIC。服务器的 NIC 再将模拟信号转成字节数据存放到内核为套接字分配的接收缓存中,最终服务器进程从接收缓存中读取数据即为源客户端进程传递过来的 RPC 指令消息。

消息从用户进程流向物理硬件,又从物理硬件流向用户进程,中间还经过了一系列的路由网关节点。

上图呈现的只是 RPC 一次消息交互的上半场,下半场是一个逆向的过程,从服务器进程向客户端进程返回响应数据。完整的一次 RPC 过程如下图所示:

下面用 Python 代码来描述上述过程。

  • Server 端死循环监听本地 8080 端口,等待客户端的连接。
  • 客户端启动时连接本地 8080 端口,紧接着发送词一个字符串 hello,然后等待服务器响应。
  • 服务器接收到客户端连接后立即收取客户端发送过来的字符串,也就是 hello,打印出来。然后立即给对方回复一个字符串 world。
  • 客户端接收到服务器发送过来的 world,马上打印出来。
  • 关闭连接,结束。
# coding: utf-8
# server

import socket

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.bind(("localhost", 8080))
sock.listen(1)  # 监听客户端连接
while True:
    conn, addr = sock.accept()  # 接收一个客户端连接
    print conn.recv(1024)  # 从接收缓冲读消息 recv buffer
    conn.sendall("world")  # 将响应发送到发送缓冲 send buffer
    conn.close() # 关闭连接

# coding: utf-8
# client

import socket

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect(("localhost", 8080))  # 连接服务器
sock.sendall("hello")  # 将消息输出到发送缓冲 send buffer
print sock.recv(1024)  # 从接收缓冲 recv buffer 中读响应
sock.close() # 关闭套接字

如果从上面代码上观察,我们其实很难看出上图所示的复杂过程。浮现在多数人脑海中往往是下面的这幅简约模型图。相比之下它要简单很多,这也正是操作系统设计的魅力所在,让你时时刻刻都在使用它却感受不到它的存在。

小结

通过本节内容,读者们对 RPC 的交互流程应该有了大致了解,但是还并不知道 RPC 之间到底交互了什么。就好比你能看到远方有几个人在说话,但是不知道他们在说啥。

下一节我们将放大细节,仔细观察 RPC 客户端服务器之间窃窃私语了什么,它们究竟是在用什么外星语言交流。

练习题

一个很有趣的小测试实验 , 请读者编写代码实现以下情景:

客户端疯狂发送请求,但是服务器不读不处理,会发生什么

本文分享自微信公众号 - 码洞(codehole)

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2018-07-23

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏IT技术精选文摘

缓存在分布式系统中的应用

缓存是分布式系统中的重要组件,主要解决高并发,大数据场景下,热点数据访问的性能问题。提供高性能的数据快速访问。 一、缓存概述 缓存是分布式系统中的重要组件,主要...

40090
来自专栏IMWeb前端团队

react 的数据管理方案:redux 还是 mobx?

本文作者:IMWeb jerytang 原文出处:IMWeb社区 未经同意,禁止转载 mobx 简介 和 redux 类似,mobx 是一个数据管理库...

47370
来自专栏FreeBuf

Joomla!3.7.0 SQL注入攻击漏洞分析

Joomla是一套世界第二流行的内容管理系统。它使用的是PHP语言加上MySQL数据库所开发的软件系统,可以在Linux、 Windows、MacOSX等各种不...

26050
来自专栏向治洪

Freeline--Android平台上的秒级编译方案

Freeline 技术揭秘 Freeline是什么? Freeline是蚂蚁金服旗下一站式理财平台蚂蚁聚宝团队15年10月在Android平台上的量身定做的一个...

30480
来自专栏数据和云

快讯:Oracle 发布了传闻已久的 18.3 RPM 安装版本

关于 Oracle 发布数据库 RPM 安装版本的传闻已经有好几年了,今天 Oracle 终于发布了这个传说中、被期待的安装包,在 OTN 上已经可以下载 Li...

13030
来自专栏Golang语言社区

关于缓存你需要知道的

About Cache 作后端开发的同学,缓存是必备技能。这是你不需要花费太多的精力就能显著提升服务性能的灵丹妙药。前提是你得知道如何使用它,这样才能够最大限度...

370130
来自专栏C/C++基础

error: '[class name]' does not name a type

从命令中可以看出,我是对源文件tc_mysql.cpp进行编译。但是却始终报如下错误:

11010
来自专栏学习有记

Python和SQL Server 2017的强大功能

25650
来自专栏进击的程序猿

ZooKeeper: Wait-free coordination for Internet-scale systems(笔记)

本文是读ZooKeeper: Wait-free coordination for Internet-scale systems的笔记,从第一手资料了解zook...

14330
来自专栏数据库新发现

快讯:Oracle 发布了传闻已久的 18.3 RPM 安装版本

关于 Oracle 发布数据库 RPM 安装版本的传闻已经有好几年了,今天 Oracle 终于发布了这个传说中、被期待的安装包,在 OTN 上已经可以下载 Li...

11940

扫码关注云+社区

领取腾讯云代金券