这是我参与「第三届青训营 -后端场」笔记创作活动的的第5篇笔记。
一、基本概念
RPC(Remote Procedure Call,远程过程调用)是一种计算机通信协议,允许调用不同进程空间的程序。RPC 的客户端和服务器可以在一台机器上,也可以在不同的机器上。程序员使用时,就像调用本地程序一样,无需关注内部的实现细节。
-
远程函数调用(RPC -Remote Procedure Calls)
- 函数映射
- 数据转换成字节流
- 网络传输
-
RPC完整过程
-
IDL文件(如Thrift,Protobuf):
通过中立的方式描述接口,使不同平台上运行的对象和用不同语言编写的程序可以相互通信
-
生成代码:
通过相应的编译工具把IDL文件转换成语言对应的静态库
-
编解码:
从内存中表示转换到字节序列称为编码,反之为解码,也可以叫做序列化和反序列化。
-
通信协议:
规范数据在网络中的传输内容和格式。除了必需的请求/响应数据外,通常包含额外的元数据。
-
网络传输:
通常基于成熟的TCP/UDP传输
-
-
RPC优点
- 单一职责,有利于分工协作和运维开发
- 可扩展性强,资源使用率更优
- 故障隔离,服务的整体可靠性更高
-
RPC缺点(RPC框架处理)
- 被调用服务宕机,调用方怎么处理
- 调用过程中发生网络异常,如何保证消息可达
- 请求量突增导致服务无法及时处理
二、分层设计
-
编解码层
-
数据格式
-
语言特定格式
如Java的java.io.Serializable
-
文本格式
JSON、XML、CSV等,可读性强
-
二进制编码
跨语言、高性能。如Protobuf和Thrift的BinaryProtocol
-
-
二进制编码
-
TLV编码(Tag、Lenght是额外开销):
Tag:标签/类型
Lenght:长度
Value:值,可嵌套TLV
-
-
选型
-
兼容性
支持自动增加新的字段,而不影响旧服务
-
通用性
支持跨平台和语言
-
性能
编码后数据大小和编码耗费时间
-
-
-
协议层
-
概念:
-
特殊结束符
一个特殊字符作为每个协议单元结束的标示
-
变长协议:
以定长加不定长的部分组成,其中定长的部分需要描述不定长的内容长度
-
-
协议构造:(Apache Thrift为例)
- LENGTH:数据包大小,不包括本身
- HEADER MAGIC:标识版本信息
- SEQUENCE NUMBER:表示数据包seqID,用于多路复用,但连接内递增
- HEADER SIXE:头部长度,从第14个字节计算到PAYLOAD前
- PROTOCOL ID:编解码方式
- TRANSFORM ID:压缩方式
- INFO ID:传递定制meta信息
- PAYLOAD:消息体
-
协议解析
-
-
网络通信层
-
Sockets API
-
网络库:
-
提供简单易用API:
- 封装底层Socket API
- 连接管理和事件分发
-
功能:
- 协议支持:tcp、udp和uds等
- 优雅退出、异常处理等
-
性能:
- 应用层buffer减少copy
- 高性能定时器、对象池等
-
-
三、关键指标
-
稳定性:
-
保障策略:
-
熔断:
保护调用方,防止被调用的服务出现问题而影响整个链路
-
限流:
保护被调用方,防止大流量压垮服务
-
超时控制:
避免浪费资源在不可用节点上
-
-
请求成功率:
- 负载均衡
- 重试
-
长尾请求(明显高于平均响应时间的小部分请求):
备份请求
-
注册中间件:
-
-
易用性:
-
开箱即用:
- 提供合理的默认参数
- 文档丰富
-
周边工具:
- 生成代码工具、脚手架工具
-
-
扩展性:
- 中间件
- 参数
- 编解码层
- 协议层
- 网络协议层
- 代码生成工具插件扩展
-
观测性:
- Log、Metric、Tracing
- 内置观测性服务
-
高性能:
-
场景:
- 单机多机
- 但连接多连接
- 单/多client 单/多server
- 不同大小的请求包
- 不同请求类型
-
目标:
- 高吞吐
- 低延迟
-
手段:
- 连接池
- 多路复用
- 高性能编解码协议
- 高性能网络库
-
四、RPC与基于HTTP的Restful API对比
- Restful API 有相对统一的标准,因而更通用,兼容性更好,支持不同的语言。HTTP 协议是基于文本的,一般具备更好的可读性。
- Restful 接口需要额外的定义,无论是客户端还是服务端,都需要额外的代码来处理,而 RPC 调用则更接近于直接调用。
- 基于 HTTP 协议的 Restful 报文冗余,承载了过多的无效信息,而 RPC 通常使用自定义的协议格式,减少冗余报文。
- RPC 可以采用更高效的序列化协议,将文本转为二进制传输,获得更高的性能。
- 因为 RPC 的灵活性,所以更容易扩展和集成诸如注册中心、负载均衡等功能。