如何设计优雅的RPC接口

  • 内容
  • 评论
  • 相关

RPC 是一种方便的网络通信编程模型,由于和编程语言的高度结合,大大减少了处理网络数据的复杂度,让代码可读性也有可观的提高。但是 RPC 本身的构成却比较复杂,由于受到编程语言、网络模型、使用习惯的约束,有大量的妥协和取舍之处。

RPC 框架的讨论一直是各个技术交流群中的热点话题,例如阿里的 dubbo、新浪微博的 motan、谷歌的 grpc 以及不久前蚂蚁金服开源的 sofa 都是比较出名的 RPC 框架。

认识 RPC(远程调用)

我们在各种操作系统、编程语言生态圈中,多少都会接触过“远程调用”的概念。一般来说,它们指的是用一行简单的代码,通过网络调用另外一个计算机上的某段程序。比如:

  • RMI(Remote Method Invoke):调用远程的方法,“方法”一般是附属于某个对象上的,所以通常 RMI 指对在远程的计算机上的某个对象,进行其方法函数的调用。
  • RPC(Remote Procedure Call):远程过程调用,指的是对网络上另外一个计算机上的,某段特定的函数代码的调用。

远程调用本身是网络通信的一种概念,它的特点是把网络通信封装成一个类似函数的调用。网络通信在远程调用外,一般还有其他的几种概念:数据包处理、消息队列、流过滤、资源拉取等待,它们的差异如下表所示:

方案 编程方式 信息封装 传输模型 典型应用
远程调用 调用函数、输入参数、获得返回值 使用编程语言的变量、类型、函数 发出请求、获得响应 Java RMI
数据包处理 调用 Send()/Recv(),使用字节码数据、编解码、处理内容 把通信内容构造成二进制的协议包 发送/接收 UDP 编程
消息队列 调用 Put()/Get(),使用“包”对象,处理其包含的内容 消息被封装成语言可用的对象或结构 对某队列存入一个消息或取出一个消息 ActiveMQ
流过滤 读取一个流或写出一个流,对流中的单元包即刻处理 单元长度很小的统一数据结构 连接、发送/接收、处理 网络视频
资源拉取 输入一个资源 ID,获得资源内容 请求或响应都包含:头部和正文 请求后等待响应 WWW

远程调用的优势

1) 屏蔽了网络层

因此在传输协议和编码协议上,我们可以选择不同的方案。比如 WebService 方案就是用的 HTTP 传输协议 +SOAP 编码协议,而 REST 的方案往往使用 HTTP+JSON 协议。

Facebook 的 Thrift 可以定制任何不同的传输协议和编码协议,可以用 TCP+Google Protocol Buffer 也可以用 UDP+JSON 等。

由于屏蔽了网络层,可以根据实际需要来独立的优化网络部分,而无需涉及业务逻辑的处理代码,这对于需要在各种网络环境下运行的程序来说,非常有价值。

2) 函数映射协议

可以直接用编程语言来书写数据结构和函数定义,取代编写大量的编码协议格式和分包处理逻辑。对于那些业务逻辑非常复杂的系统,比如网络游戏,可以节省大量定义消息格式的时间。

函数调用模型非常容易学习,不需要学习通信协议和流程,让经验较浅的程序员也能很容易的开始使用网络编程。

远程调用的缺点

1) 增加了性能消耗

由于把网络通信包装成“函数”,需要大量额外的处理,比如需要预生产代码,或者使用反射机制。这些都是额外消耗 CPU 和内存的操作。而且为了表达复杂的数据类型,比如变长的类型 string/map/list,这些都要数据包中增加更多的描述性信息,则会占用更多的网络包长度。

2) 不必要的复杂化

如果是为了某些特定的业务需求,比如传送一个固定的文件,那么应该用 HTTP/FTP 协议模型;如果为了做监控或者 IM 软件,用简单的消息编码收发会更快速高效;如果是为了做代理服务器,用流式的处理会很简单。另外,如果要做数据广播,那么消息队列会很容易做到,而远程调用这几乎无法完成。

因此,远程调用最适合是业务需求多变或者网络环境多变的场景。

RPC 结构拆解

RPC 的结构如下图所示:

RPC 结构图
图:RPC 结构图

本文标题:如何设计优雅的RPC接口

本文地址:https://www.hosteonscn.com/6002.html

评论

0条评论

发表评论

邮箱地址不会被公开。 必填项已用*标注