RPC学习 | 青训营笔记

128 阅读5分钟

这是我参与「第三届青训营 -后端场」笔记创作活动的第2篇笔记

通过这节课的学习,学习了解RPC的基本概念和相关知识,以下是课程学习笔记。

基本概念

本地函数调用

简单的例子(实际上编译器经常会做优化的)

image.png

远程函数调用(RPC-Remote Procedure Calls)

image.png 函数映射:

  • 在本地,函数体直接通过函数指针来指定调用哪个方法,编译器就自动调用相应的函数指针
  • 在远程调用中,函数指针是不行的,因为两个进程的地址完全不一样。每个函数都有自己的ID,在做RPC时要附上这个ID,还需要有ID和函数的对照关系表,通过ID找到函数并执行。 参数值传递:
  • 在本地,只需要把参数压到栈里,然后函数自己去栈里读就行
  • 在远程调用中,客户端服务端是不同的进程,不能通过内存来传递函数。需要客户端把参数先转成一个字节流,传给服务端后,再把字节流转成自己能读取的格式。 网络传输: 如何保持在网络上高效稳定的传输

一次RPC的完整过程

image.png

RPC的好处

1单一职责,有利于分工协作和运维开发
2.可扩展性强,资源使用率更优
3.故障隔离,服务的整体可靠性更高

RPC带来的问题

1服务宕机,对方应该如何处理?
2在调用过程中发生网络异常,如何保证消息的可达性?
3.请求量突增导致服务无法及时处理,有哪些应对措施?

使用RPC框架解决

RPC框架-分层设计

主要分为三层:编解码层、协议层、通信网络层 以Apache Thrift为例: image.png

编解码层

生成代码

image.png

数据格式

语言特定的格式:许多编程语言都内建了将内存对象编码为字节序列的支持,例Java有java.io.Serializable
文本格式:JSONXMLCSV等文本格式,具有人类可读性
二进制编码:具有跨语言和高性能等优点,常见的有ThriftBinaryProtocolProtobuf

编码格式的选型

兼容性:支持自动增加新的字段,而不影响老的服务,这将提高系统的灵活度
通用性:支持跨平台、跨语言
性能:从空间和时间两个维度来考虑,也就是编码后数据大小和编码耗费时长

协议层

协议是双方确定的交流语义,比如:我们设计一个字符串传输的协议,它允许客户端发送一个字符串,服务端接收到对应的字符串。
特殊结束符:过于简单,对于一个协议单元必须要全部读入才能够进行处理,除此之外必须要防止用户传输的数据不能同结束符相同,否则就会出现紊乱
HTTP协议头就是以回车(CR)加换行(LF)符号序列结尾。
变长协议:一般都是自定义协议,有header和payload组成,会以定长加不定长的部分组成,其中定长的部分需要描述不定长的内容长度,使用比较广泛

image.png

协议构造:

image.png

协议解析:

image.png

网络通信层

Sockets API

应用层和传输层之间

知道两个信息:ip、端口

创建socketbind操作,进行绑定,监听,accept(接收客户端发起的请求),read+writer通信,close

网络库

提供易用API:封装底层Socket;API连接管理和事件分发
功能:协议支持: tcp、udp 和uds等;优雅退出、异常处理等
性能:应用层 buffer 减少copy;高性能定时器、对象池等

关键指标

稳定性-保障策略

image.png

稳定性-请求成功率

重试有放大故障的风险
首先,重试会加大直接下游的负载。如下图,假设A服务调用B服务,重试次数设置为r(包括首次请求),当B高负载时很可能调用不成功,这时A调用失败重试BB服务的被调用量快速增大,最坏情况下可能放大到r倍,不仅不能请求成功,还可能导致B的负载继续升高,甚至直接打挂。
防止重试风暴,限制单点重试和限制链路重试

image.png

稳定性-长尾请求

长尾请求一般是指明显高于均值的那部分占比较小的请求。
业界关于延迟有一个常用的P99标准:单个请求响应耗时从小到大排序,顺序处于99%位置的值即为P99值,后面的1%就可以认为是长尾请求。
在较复杂的系统中,长尾延时总是会存在,造成的原因很多,例如:网络抖动、GC、系统调度

image.png

稳定性-注册中间件

image.png

易用性

开箱即用:合理的默认参数选项、丰富的文档
周边工具:生成代码工具、脚手架工具

扩展性

Middleware
Option
编解码层
协议层
网络传输层
代码生成工具插件扩展

观测性

Log、Metric、Tracing
内置观测性服务

高性能

场景:

单机多机
单连接多连接
单/多client|server
不同大小的请求包
不同请求类型:pingpong、streaming等

目标

高吞吐
低延迟
两者都很重要,甚至大部分场景下低延迟更重要

手段

连接池
多路复用:可以大大减少连接带来的资源消耗,并且提升了服务端性能
高性能编解码协议
高性能网络库