知乎上看到的一个解释,解释的太精炼太直接,忍不住在这记录一下。

知乎地址:https://www.zhihu.com/question/25536695

本地过程调用

RPC就是要像调用本地的函数一样去调远程函数。在研究RPC前,我们先看看本地调用是怎么调的。假设我们要调用函数Multiply来计算lvalue * rvalue的结果:

int Multiply(int l, int r) {
int y = l * r;
return y;
} int lvalue = ;
int rvalue = ;
int l_times_r = Multiply(lvalue, rvalue);

那么在第8行时,我们实际上执行了以下操作:

  1. 将 lvalue 和 rvalue 的值压栈
  2. 进入Multiply函数,取出栈中的值10 和 20,将其赋予 l 和 r
  3. 执行第2行代码,计算 l * r ,并将结果存在 y
  4. 将 y 的值压栈,然后从Multiply返回
  5. 第8行,从栈中取出返回值 200 ,并赋值给 l_times_r

以上5步就是执行本地调用的过程。

远程过程调用带来的新问题

在远程调用时,我们需要执行的函数体是在远程的机器上的,也就是说,Multiply是在另一个进程中执行的。这就带来了几个新问题:

  1. Call ID映射。我们怎么告诉远程机器我们要调用Multiply,而不是Add或者FooBar呢?在本地调用中,函数体是直接通过函数指针来指定的,我们调用Multiply,编译器就自动帮我们调用它相应的函数指针。但是在远程调用中,函数指针是不行的,因为两个进程的地址空间是完全不一样的。所以,在RPC中,所有的函数都必须有自己的一个ID。这个ID在所有进程中都是唯一确定的。客户端在做远程过程调用时,必须附上这个ID。然后我们还需要在客户端和服务端分别维护一个 {函数 <--> Call ID} 的对应表。两者的表不一定需要完全相同,但相同的函数对应的Call ID必须相同。当客户端需要进行远程调用时,它就查一下这个表,找出相应的Call ID,然后把它传给服务端,服务端也通过查表,来确定客户端需要调用的函数,然后执行相应函数的代码。
  2. 序列化和反序列化。客户端怎么把参数值传给远程的函数呢?在本地调用中,我们只需要把参数压到栈里,然后让函数自己去栈里读就行。但是在远程过程调用时,客户端跟服务端是不同的进程,不能通过内存来传递参数。甚至有时候客户端和服务端使用的都不是同一种语言(比如服务端用C++,客户端用Java或者Python)。这时候就需要客户端把参数先转成一个字节流,传给服务端后,再把字节流转成自己能读取的格式。这个过程叫序列化和反序列化。同理,从服务端返回的值也需要序列化反序列化的过程。
  3. 网络传输。远程调用往往用在网络上,客户端和服务端是通过网络连接的。所有的数据都需要通过网络传输,因此就需要有一个网络传输层。网络传输层需要把Call ID和序列化后的参数字节流传给服务端,然后再把序列化后的调用结果传回客户端。只要能完成这两者的,都可以作为传输层使用。因此,它所使用的协议其实是不限的,能完成传输就行。尽管大部分RPC框架都使用TCP协议,但其实UDP也可以,而gRPC干脆就用了HTTP2。Java的Netty也属于这层的东西。

所以,要实现一个RPC框架,其实只需要把以上三点实现了就基本完成了。

Call ID映射可以直接使用函数字符串,也可以使用整数ID。映射表一般就是一个哈希表。

序列化反序列化可以自己写,也可以使用Protobuf或者FlatBuffers之类的。

网络传输库可以自己写socket,或者用asio,ZeroMQ,Netty之类。

作者:洪春涛

[转]什么是 RPC?的更多相关文章

  1. 从RPC开始(一)

    这是一篇关于纯C++RPC框架的文章.所以,我们先看看,我们有什么? 1.一个什么都能干的C++.(前提是,你什么都干了) 2.原始的Socket接口,还是C API.还得自己去二次封装... 3.C ...

  2. RPC 使用中的一些注意点

    最近线上碰到一点小问题,分析其原因发现是出在对 RPC 使用上的一些细节掌握不够清晰导致.很多时候我们做业务开发会把 RPC 当作黑盒机制来使用,但若不对黑盒的工作原理有个基本掌握,也容易犯一些误用的 ...

  3. 谈谈如何使用Netty开发实现高性能的RPC服务器

    RPC(Remote Procedure Call Protocol)远程过程调用协议,它是一种通过网络,从远程计算机程序上请求服务,而不必了解底层网络技术的协议.说的再直白一点,就是客户端在不必知道 ...

  4. 游戏编程系列[1]--游戏编程中RPC协议的使用[3]--体验

    运行环境,客户端一般编译为.Net 3.5 Unity兼容,服务端因为用了一些库,所以一般为4.0 或往上.同一份代码,建立拥有2个项目.客户端引用: WindNet.Client服务端引用: OpL ...

  5. python通过protobuf实现rpc

    由于项目组现在用的rpc是基于google protobuf rpc协议实现的,所以花了点时间了解下protobuf rpc.rpc对于做分布式系统的人来说肯定不陌生,对于rpc不了解的童鞋可以自行g ...

  6. spider RPC入门指南

    本部分将介绍使用spider RPC开发分布式应用的客户端和服务端. spider RPC中间件基于J2SE 8开发,因此需要确保服务器上安装了JDK 8及以上版本,不依赖于任何额外需要独立安装和配置 ...

  7. Netty实现高性能RPC服务器优化篇之消息序列化

    在本人写的前一篇文章中,谈及有关如何利用Netty开发实现,高性能RPC服务器的一些设计思路.设计原理,以及具体的实现方案(具体参见:谈谈如何使用Netty开发实现高性能的RPC服务器).在文章的最后 ...

  8. 基于Netty打造RPC服务器设计经验谈

    自从在园子里,发表了两篇如何基于Netty构建RPC服务器的文章:谈谈如何使用Netty开发实现高性能的RPC服务器.Netty实现高性能RPC服务器优化篇之消息序列化 之后,收到了很多同行.园友们热 ...

  9. Redola.Rpc 的一个小目标

    Redola.Rpc 的一个小目标 Redola.Rpc 的一个小目标:20000 tps. Concurrency level: 8 threads Complete requests: 20000 ...

  10. 闲话RPC调用

    原创文章转载请注明出处:@协思, http://zeeman.cnblogs.com 自SOA架构理念提出以来,应用程序间如何以最低耦合度通信的问题便呈现在所有架构师面前. 互联网系统的复杂度让我们不 ...

随机推荐

  1. SVN更新的问题

    更新的时候一直遇到"Base checksum mismatch on"或者"Checksum mismatch while updating",其它文件可以提 ...

  2. django数据模型中 null=True 和 blank=True 有什么区别?

    null 如果为 True , Django 在数据库中会将空值(empty)存储为 NULL .默认为 False . blank 设置字段是否可以为空,默认为False(不允许为空) 和null的 ...

  3. django的数据库操作

    ORM是通过使用描述对象和数据库之间映射的元数据,将程序中的对象自动持久化到关系数据库中,ORM在业务逻辑层和数据库层之间充当了桥梁的作用. django的交互式shell python manage ...

  4. ASP.NET Core开发-读取配置文件Configuration appsettings.json

    https://www.cnblogs.com/linezero/p/Configuration.html ASP.NET Core 是如何读取配置文件,今天我们来学习. ASP.NET Core的配 ...

  5. 【转】QT中QDataStream中浮点数输出问题

    先上代码: C/C++ code   ? 1 2 3 4 5 6 7 8 9 10 11 12 13 int main(int argc, char *argv[]) {     QApplicati ...

  6. 如何查看Isilon节点的硬件信息?

    Isilon节点虽然是一个Linux,但是很多linux下常用的命令都没有,比如说看内存的.笔者经过试验,列出了一些可用的命令. 查看硬件状态 isi_hw_status 查看内存 sysctl hw ...

  7. Documentation/PCI/pci-iov-howto.txt

    Chinese translated version of Documentation/PCI/pci-iov-howto.txt If you have any comment or update ...

  8. Dictionary 的几种遍历方法

    Dictionary 的几种遍历方法 Dictionary<string, int>dic = newDictionary<string, int>(); 方法1 foreac ...

  9. windows无法访问vmware搭建好虚拟机linux web服务器

    [前置条件] vmware搭建好虚拟机web服务器 ,但是本机就是无法访问的解决办法. linux虚拟机的网络选择Bridged 桥接到本机网卡. 具体情况如下 : 1.本机能ping通虚拟机 2.虚 ...

  10. Robotframework(2):创建RF第一条可执行的用例

    转载:http://www.cnblogs.com/CCGGAAG/p/7800323.html 上篇,我们说了如何配置基础的环境,配置好了python2.wxPython .robot framew ...