RPC原理与实现 | 青训营笔记

46 阅读5分钟

这是我参与「第五届青训营 」伴学笔记创作活动的第 9 天

主要内容

经过这节课的学习,主要是了解了RPC的基本概念以及组成原理,以及关键性指标,之后又通过实例加深了理解。

具体内容

RPC基本概念

RPC(Remote Produce Calls),即远程过程调用。
RPC需要解决函数映射、数据转换为字节流、网络传输这三个问题。其最早是Nelson于1984年发表的论文提到的,论文中认为其过程由User、User-Stub、RPC-Runtime、Server-Stub、Server这五部分组成。

在实际使用中,主要使用到了IDL文件,它的作用是通过中立的方式描述接口,使得在不同平台上的程序等可以互相通信。之后了解了编解码(也叫做序列化与反序列化)、通信协议、网络传输等概念。

RPC的使用带来了好处但也带来了问题:
优点:单一职责,便于分工协作和运维;可扩展性强;故障隔离,整体可用性更高。
问题:需要设法保证消息的可达性;当请求量突增时难以处理。
使用RPC出现的问题,需要由RPC框架来处理。因此接下来学习RPC框架的相关知识。

RPC框架

RPC框架主要分为三层:编解码层、协议层和网络通信层。
之后学习了Apache Thrift的分层设计是什么样的。 客户端和服务端会依据相同的IDL文件,生成不同语言的CodeGen。

编解码层

编码的数据格式通常有语言特定的格式、文本格式(JSON、CSV等)和二进制编码。每种数据格式都有优点和缺点。语言特定的格式的优点是方便,便于恢复,但是缺点是兼容性较差,文本格式的优点是人类可读性高,但是描述并不严谨,二进制编码具有跨语言和高性能等优点。

TLV编码由Tag、Length、Value三部分组成。
在选择编码格式时,需要同时从兼容性、通用性和性能(从空间和时间两个维度)都角度来考虑。兼容性是指增加新的字段时不会影响老的服务,而通用性则是指跨平台、跨语言。

协议层

编码后只是把数据转换成字节流,但是不会直接把这些字节流打包发送出去,而是添加其他的字段。
有两种:特殊结束符和变长协议。特殊结束符是指用特殊结束符作为每个协议单元结束的标志(比如“\r”,“\n”),变长协议则是以定长加不定长的部分组成,定长部分需要描述不定长的内容长度。 之后学习了协议的构造,包括LENGTH, HEADER MAGIC,HEADER SIZE等,并且了解了各个部分是什么。最后是协议解析。

网络通信层

会使用系统提供的Sockets API,该部分支持的网络协议有tcp、udp、uds等,同时支持优雅退出、异常处理等。

RPC框架的关键指标

RPC框架的关键指标有稳定性、易用性、扩展性、观测性和高性能,之后详细了解了每个部分。在设计时都需要考虑。

稳定性

会使用超时控制、熔断、限流等保障策略。熔断保护调用方防止,限流保护被调用方,防止大流量把服务压垮,超时控制则可以避免资源浪费在不可用的节点上。这三种保障策略都可以认为是所谓的降级措施。
稳定性的一个重要指标是请求成功率。提高请求成功率的方式有负载均衡(避免某个节点的压力太大)和重试。此外稳定性还却决于常委请求。长尾请求指。框架往往使用注册中间件的形式来实现超时、熔断、重试等。

易用性

易用性需要开箱即用周边工具。开箱即用顾名思义,拿到手就能使用,要做到这点,需要合理的默认参数、方便的命令行工具以及丰富的文档。周边工具有生成代码工具和脚手架工具。

扩展性

PRC框架应该提供丰富的扩展点,比如说核心的传输层和协议层。

观测性

PRC框架既有内置的观测服务,也通过Log、Metric、Tracing实现。

高性能

其目标就是实现高吞吐(在一定时间内尽可能处理多的请求)和低延迟(一次请求发出去返回时间尽可能短),实际应用中低延迟更重要。 在实际衡量时要考虑场景,包括单机多机、单连接多连接、请求包的大小、请求类型等多个因素。在不同场景下,同一个PRC框架的表现也是不一样的。 实现的手段有连接池、多路复用、高性能编解码协议、使用高性能网络库。

企业实践

主要通过Kitex,了解了RPC框架的各个部分。学习了Kitex的整体架构组成是什么样的,以及各个功能的实现是如何做的,比如说自研的网络库Netpoll、网络库优化(调度优化等)、编解码优化(Codegen、JIT)。

总结

经过这节课的学习,我学习了什么是RPC框架,以及RPC框架的组成和关键指标,经过这节课的学习,我进一步了解了RPC框架。所以,要如何设计一个RPC框架呢?