架构师之路 - RPC 理解
本文是阅读老钱的《深入理解RPC:基于Python自建分布式高并发RPC服务》的笔记及摘录。
最早了解到的系统之间交互有Web service,那还是在学生时代。还没有彻底搞明白其运行原理,便接触了一种新的系统交互方式,或者叫准则更合适。那便是 RestFul。这种系统交互方式伴随了我的职业生涯好久,直到现在系统之间的交互,我的首选还是restful。它是一种简单交互方式,将请求信息看做资源,使用JSON这种数据结构作为传输格式,基于http协议,简单易用。只要把我们的http返回页面改为JSON格式的数据,并遵循一定的restful准则即可。restful 并没有严格的去限制你的使用,更多是提供了一种以http协议为基础的交互思路。
后来,接触到了RPC
这个词,知道它是也是一种远程过程调用方式,并且呢在微服务和分布式系统中使用的比较广泛。看到有这样一本书,试读了下可以学到东西,便买入深入研读下。
# RPC 介绍
RPC(Remote Procedure Call),远程过程调用,是一种分布式系统中常用跨机器的通信方法,更多的是指跨机器交互中的长连接交互。
RPC,传统意义上讲是指长连接数据交互,区别于http
即用即走的短连接,严格来说http
也算是一种特殊的RPC服务,随着http1.1
中对长连接的支持,区别已经越来越小。
RPC的应用非常广泛,主要应用在大中型分布式系统中的组件交互,可以这样理解:各种夸网络协议的「长连接」系统交互中都使用了RPC或者类RPC。
其他分布式通信解决方案还有:分布式消息队列、HTTP请求调用、数据库和分布式缓存等。
各大厂开源的RPC框架有:
- Google: gRPC
- Facebook: Thrift
- Twitter: Finagle
- 百度:bRPC
- 腾讯:Tars
- 阿里:Dubbo、SOFA
- 新浪:Motan
# RPC 交互流程
RPC 是两个子系统之间进行的直接消息交互,它使用操作系统提供的套接字(sockect)来作为消息的载体,以特定的消息格式(需要序列化)来定义消息内容和边界。
可以这样理解,RPC是对底层通信和交互协议的一个封装,便于上层使用。
# RPC 协议构成
RPC 消息协议组成:
# 消息边界
因为 RPC 是在一条TCP链路上进行多次消息的交互,所以交互过程中为了区分一条一条消息的消息,必须将消息的边界定义好。
消息边界分隔有两种方式:
- 特殊符号法:使用特殊符号,最长用的是
\r\n
。可读性强,但是只能传输文本。 - 长度前缀法:在消息前加 4 字节长度的整数值,标记消息体的长度。此方式常用于二进制类型的消息。可读性差,可以传输文本和内容。
# 消息结构
消息结构分为两种:
显示的消息结构:消息的结构有自身决定,可读性高,但是为了表示结构,传输时冗余字段多,消耗更多的流量。如:JSON格式。
隐式的消息结构:在TCP链接创建时,服务端和客户端便规定好消息结构,以后交互直接发送消息的值即可。消息的可读性差,但是确实节省了不少传输流量。
# 消息压缩
消息在传输过程中为了节省带宽需要压缩。但是是否需要压缩,要根据具体业务场景。不要为了压缩占用大量系统资源,导致正常系统服务出现问题。
# 流量的优化
消息传递中,必然是占用字节越少,效率的流量越少,传输速度也越快了。优化流量这里思路便是,尽量减少消息的字节占用。
- 使用变长整数varint,来表示整数。
- 使用 zigzag 编码 来表示负数。
# RPC 通信协议列举分析
# Redis 通信协议分析
Redis 作者自己设计了一套本文通信协议 RESP。按照RPC消息结构来分析如下:
- 消息边界:RESP使用特殊符号
\r\n
来区分多次消息。 - 消息结构:使用文本形式来传送消息。
- 流量优化:网络流量倾斜进行极致优化,而是选择了照顾协议的直观性、可理解性。
更多协议详情,可参考官方相关文档 (opens new window)。
# Protobuf
Protobuf 协议是 Google 开源的二进制 RPC 通讯协议,它可能是互联网开源项目中使用最为广泛的 RPC 协议。
- 消息边界:没有定义消息边界,也就是没有消息头。消息头一般由用户自己定义,通常使用长度前缀法来定义边界
- 消息结构:使用二进制流传送消息。
- 流量优化:通过对消息格式的设计优化,充分压榨了消息体积,减小了传输使用的流量。
扩展阅读:
# RPC vs HTTP vs WebService
RPC
远程过程调用,就是在另外一台服务器上有一段代码(函数),你可以通过网络远程调用它。用什么协议(http,tcp,udp…),传输什么数据格式(json,xml,二进制...)你都可以自己控制。
HTTP API
基于应用层的HTTP协议,通常是以一种web的方式,对外提供以JSON或字符串作为数据格式的接口服务,例如著名的 restful规则。
WebService
是一种SOAP方式的web服务。SOAP用来描述传递信息的格式, WSDL用来描述如何访问具体的接口,UDDI用来管理,分发,查询webService。基于http协议,使用xml格式来传递数据。
现阶段个人理解:
- RPC 广义上来讲,是远程过程调用,即跨机器的函数调用。传输协议和格式可自己控制。包括基于TCP协议的一些通信协议实现的过程调用和基于http协议实现的过程调用。如:restful API、WebService及gRPC等一些框架实现。
- RPC 狭义上来讲的话,通常是基于TCP/IP协议,通过二进制流或文本的数据格式来传输的一些通信方法,如:gRPC。