这是我参与「第三届青训营 -后端场」笔记创作活动的的第4篇笔记
如果有错误和其他意见,麻烦留言指正💖
RPC框架深入浅出
基本概念
引入:
- 本地函数调用
- 远程函数调用
- RPC需要解决: (1) 函数映射(本地调用函数指针直接调用,但是远程调用为两个进程,地址空间不一样,所以每个函数有自己的ID,通过ID找到远程函数)。
(2)数据转换成字节流(本地只需要压栈,在读取)。
(3)网络传输(要保证高效)
一次RPC的完整过程
-
IDL(Interface description language)文件:
通过中立的方式描述接口,是使得不同平台上运行的对象和不同语言编写的程序能相互通信
-
生成代码
通过编译器把IDL文件转换成语言对应的静态库
-
解编码
序列化和反序列化
-
通信协议
规范了数据在网络中的和出传输内容和格式。
-
网络传输(TCP/UDP)
RPC好处
1. 单一职责,利于分工
2. 可扩展性强
3. 故障隔离
RPC分层设计
编解码层/协议层/网络通信层
以Thrift为例:
编解码层
数据格式:编程语言特定格式, 文本格式(json,xml,csv),二进制编码(thrift的BinaryProtocol——TLV编码)
TLV编码:
1. Tag:标签
2. Length:长度
3. Value:值,也可以是个TLV结构
协议层
概念:(一般以下常见的两种)
- 特殊结束符 作为每个单元结束的标志
- 变长协议
看一个具体例子————协议构造:
网络通信层 ————Sockets API
(Sockets API 图)
现实中用封装好的网络库来作为框架的网络通信层:
-
提供易用的API
他会封装底层Sockets API,连接管理和事件分发
-
功能
协议支持:tcp,udp,uds等
-
性能
可以用应该层buffer来减少拷贝,高性能定时器,对象池等
关键指标
稳定性/易用性/扩展性/观测性/高性能
高性能:
- 目标:高吞吐,低延迟
- 手段:连接池, 多路复用, 高性能编解码协议, 高性能网络库
- 场景: 单机多用, 单机多连 ......
实践
整体架构 —— Kitex
Kitex Core: 核心组件
Kitex Byted: 与公司内部基础设施集成(字节)
Kitex Tool: 代码生成工具
背景: 原生库无法感知连接状态,也存在goroutine暴涨的风险
网络库: Netpoll ——建立goroutine池,复用goroutine等 (有网络库优化和编解码优化等优点)
官方文档:
示例
以下是Kitex仓库示例运行:
-
进入示例仓库的
hello目录cd kitex-examples/hello -
运行 server
go run . -
运行 client
另起一个终端后,
go run ./client
合并部署
微服务过微过多,传输和序列化开销大,于是将亲和力强的服务尽可能调度到一个物理机,远程RPC调用优化为本地ICP调用。