RPC框架深入浅出 | 青训笔记

107 阅读3分钟

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

如果有错误和其他意见,麻烦留言指正💖

RPC框架深入浅出

基本概念

引入:

  1. 本地函数调用

image.png

  1. 远程函数调用

image.png

  1. RPC需要解决: (1) 函数映射(本地调用函数指针直接调用,但是远程调用为两个进程,地址空间不一样,所以每个函数有自己的ID,通过ID找到远程函数)。

(2)数据转换成字节流(本地只需要压栈,在读取)。

(3)网络传输(要保证高效)

一次RPC的完整过程

image.png

  1. IDL(Interface description language)文件:

    通过中立的方式描述接口,是使得不同平台上运行的对象和不同语言编写的程序能相互通信

  2. 生成代码

    通过编译器把IDL文件转换成语言对应的静态库

  3. 解编码

    序列化和反序列化

  4. 通信协议

    规范了数据在网络中的和出传输内容和格式。

  5. 网络传输(TCP/UDP)

RPC好处

1. 单一职责,利于分工
2. 可扩展性强
3. 故障隔离

RPC分层设计

编解码层/协议层/网络通信层

image.png

以Thrift为例:

编解码层

数据格式:编程语言特定格式, 文本格式(json,xml,csv),二进制编码(thrift的BinaryProtocol——TLV编码)

TLV编码:
1. Tag:标签
2. Length:长度
3. Value:值,也可以是个TLV结构

协议层

概念:(一般以下常见的两种)

  1. 特殊结束符 作为每个单元结束的标志

image.png

  1. 变长协议

image.png

看一个具体例子————协议构造:

image.png

网络通信层 ————Sockets API

image.png (Sockets API 图)

现实中用封装好的网络库来作为框架的网络通信层:

  1. 提供易用的API

    他会封装底层Sockets API,连接管理和事件分发

  2. 功能

    协议支持:tcp,udp,uds等

  3. 性能

    可以用应该层buffer来减少拷贝,高性能定时器,对象池等

关键指标

稳定性/易用性/扩展性/观测性/高性能

高性能:

  1. 目标:高吞吐,低延迟
  2. 手段:连接池, 多路复用, 高性能编解码协议, 高性能网络库
  3. 场景: 单机多用, 单机多连 ......

实践

整体架构 —— Kitex

image.png

Kitex Core: 核心组件

Kitex Byted: 与公司内部基础设施集成(字节)

Kitex Tool: 代码生成工具

背景: 原生库无法感知连接状态,也存在goroutine暴涨的风险

网络库: Netpoll ——建立goroutine池,复用goroutine等 (有网络库优化和编解码优化等优点)

官方文档:

Kitex

Netpoll

示例

以下是Kitex仓库示例运行

  1. 进入示例仓库的 hello 目录

    cd kitex-examples/hello

  2. 运行 server

    go run .

  3. 运行 client

    另起一个终端后,go run ./client

image.png

image.png

合并部署

微服务过微过多,传输和序列化开销大,于是将亲和力强的服务尽可能调度到一个物理机,远程RPC调用优化为本地ICP调用。