这是我参与「第五届青训营」伴学笔记创作活动的第9天。本篇为第五届字节跳动青训营-寒假专场-后端基础课程的笔记。
RPC 入门
RPC-remote procedure calls-远程函数调用。
与之相对的是==本地函数调用==(这个过程就很常见了,都在本地执行)
相较于本地调用RPC具有以下特点: 1. 首先函数需要映射 2. 数据转为字节流(本地调用只需参数压栈) 3. 网络传输(需要某种协议,两个进程)
一个完整的RPC过程
- 通过完整的IDL-Interface Description Language 文件,进行代码生成(通过编译工具将上述文件转为静态库)
- 基于通信协议对调用内容的编码解码
- 进行网络传输:一般基于成熟网络库走TCP/UDP
RPC 的优劣势
- 优点
- 可拓展
- 故障隔离
- 单一职责:方便协作开发和运维
- 坏处
- 调用异常
- 服务宕机
- 网络传输不畅
- 调用异常
RPC框架的架构
==思想:分层设计==
优点:
- 结构清晰
- 松耦合
- 适合协作开发,易于调试
分层式结构同样也具有一些缺陷:
- 降低了系统的性能。
- 有时会导致级联的修改。
分层示意图:
IDL 文件转换
graph TD
Client --> IDLFile
Server --> IDLFile
IDLFile --generate--> Golang
IDLFile --generate--> C++
IDLFile --generate--> Java
编解码
常见的编解码解决方案有:
- 基于特定编码格式的:比如:
java.io.Serializable - 文本:
JSON, XML, CSV - 二进制编码(protobuf等等)
- 跨平台
- 高性能
如何在实际项目中选型?
- 根据兼容性
- 通用性
- 性能(数据传输量,处理耗时)
RPC框架的架构关键属性
- 稳定性保障: 1. 熔断(保护调用方) 2. 限流(保护被调用方) 3. 超时控制(比如重试) 4. 提高请求成功率 1. 负载均衡 2. 重试 5. 长尾请求(部分响应时间超过平均同类请求time的请求)的优化 1. backup Request 6. 注册中间件
- 易用性: 1. 开箱即用:合理提供默认参数,以及丰富的文档 2. 丰富高效的周边工具 1. 代码生成 2. 脚手架工具 3. ...
- 可拓展性
- 可观测性(方便测试,运维) 1. Log 2. Metric 3. Tracing 4. 内置观测性服务
- 性能 1. 高吞吐 2. 低延迟 3. 当然上述不是都能达到极致,需要根据场景判断
RPC框架设计实战
- 网络库优化
- 读写并行无锁,nocopy读写
- 对象池化,减少GC开销
- 编解码优化
- Codegen
- 预计算分配内存
- JIT
- 动态编译技术
- Codegen
- 合并部署:解决微服务过微,传输序列化开销越来越大的问题
- 将亲和性强的服务实例尽可能调度到同一个物理机:远程RPC优化为IPC调用,这样大大提高稳定性和响应时间,充分利用系统资源