这是我参与「第三届青训营 -后端场」笔记创作活动的的第13篇笔记, 本文主要介绍了RPC框架的基本知识。
基本概念
远程函数调用
RPC需要解决的问题
- 函数映射:
-
- 本地调用直接用函数指针
- 远程调用的话每个方法都要有自己的id,rpc框架要附上这个id
- 数据转化为字节流:传参
- 网络传输
RPC概念模型
一次RPC的完整过程
- IDL (Interface description language) :文件IDL通过一种中立的方式来描述接口,使得在不同平台上运行的对象和用不同语言编写的程序可以相互通信
- 生成代码:通过编译器工具把IDL文件转换成语言对应的静态库
- 编解码:从内存中表示到字节序列的转换称为编码,反之为解码,也常叫做序列化和反序列化
- 通信协议 :规范了数据在网络中的传输内容和格式。除必须的请求/响应数据外,通常还会包含额外的元数据
- 网络传输:通常基于成熟的网络库走TCP/UDP传输
RPC好处
1.单一职责,有利于分工协作和运维开发
2.可扩展性强,资源使用率更优
3.故障隔离,服务的整体可靠性更高
RPC的问题
1.服务宕机,对方应该如何处理?
2.在调用过程中发生网络异常,如何保证消息的可达性?
3.请求量突增导致服务无法及时处理,有哪些应对措施?
分层设计
编解码层
编解码层--生成代码
编解码层 数据格式
- 语言特定的格式
-
- 许多编程语言都内建了将内存对象编码为字节序列的支持,例如Java 有 java.io.Serializable
- 非常方便,可以用很少的额外代码实现内存对象的保存和恢复
- 与特定的编程语言深度绑定,其他语言很难读取,安全性和兼容性差
- 文本格式
-
- JSON、XML、 CSV 等文本格式,具有人类可读性
- 数字编码有歧义,xml和csv无法区分数字和字符串
- json不能区分整数 和浮点数,不能指定精度
- JSON再一些语言中的序列化和反序列化需要采用反射机制,性能比较差
- 二进制编码:
-
- 具备跨语言和高性能等优点,常见有Thrift的BinaryProtocol, Protobuf等
编解码层 二进制编码
TLV编码
- Tag:标签,可以理解为类型
- Lenght:长度
- Value: 值, Value 也可以是个TLV结构
编解码层 选型
- 兼容性:支持自动增加新的字段,而不影响老的服务,这将提高系统的灵活度
- 通用性:支持跨平台、跨语言
- 性能:从空间和时间两个维度来考虑,也就是编码后数据大小和编码耗费时长
协议层
概念
- 特殊结束符:需要知道哪里开始哪里结束
协议构造
协议解析
网络通信层
Sockets API
网络库
关键指标
稳定性-保障策略
稳定性-请求成功率
稳定性-长尾请求
请求响应耗时明显高于平均响应时间
使用backup request替代普通请求(右图)
稳定性-注册中间件
易用性
- Suite
- 周边工具
扩展性
观测性
- log
- Metric:监控面板
- Tracing
高性能
企业实践
整体架构-Kitex
自研网络库
背景
Netpoll
扩展性设计
性能优化-网络库优化
性能优化-编解码优化
合并部署
- 传输和序列化开销大
- 将亲和性强的服务实例尽可能调度到同一个物理机,将RPC转化为本地IPC
- 合并部署只适用于字节内部环境
\