RPC
这是我参与「第五届青训营」伴学笔记创作活动的第11天
基本概念
本地函数调用
func main(){
var a = 2
var b = 3
res:=calculate(a,b)
fmt.Println(res)
return
}
func calculate(x,y int){
z:=x*y
return z
}
远程函数调用(RPC-Remote Procedure Calls)
问题:函数映射、数据转换成字节流、网络传输
概念模型
User、User_stub、RPC_Runtime、Server-Stub、Server
完整过程
概念:
- IDL:中立的描述接口语言
- 生成代码:编译器把IDL转换成对应语言静态库
- 编解码:从内存中表示到字节序列的转换称为编码
- 通信协议:规范了数据在网络中的传输内容和格式
- 网络传输:基于TCP/UDP 好处:
- 单一职责,有利于分工和运维
- 可扩展性强
- 故障隔离,服务整体性能高 问题:
- 服务宕机
- 网络异常
- 请求量突增
分层设计
编解码
数据格式
分类:
- 语言特定:兼容性不好
- 文本格式:人类可读性
- 二进制编码:跨语言、高性能 TLV编码:
- Tag:标签(类型)
- Length:长度
- Value:值(也可是TLV结构) 例子:
struct Person{
1: required string userName,
2: optional i64 favoriteNumber,
3: optional list<string> interests
}
选型
- 兼容性
- 通用型
- 性能
协议
概念:
- 特殊结束符:特殊字符作为消息结束标示
- 变长协议:定长部分描述不定长的内容长度
协议构造:
协议解析:
MagicNumber->PayloadCodec->Payload
网络通信
Socket API
网络库
- 提供易用API:封装socket API、连接管理和事件分发
- 功能:tcp/udp/uds等、优雅退出、异常处理
- 性能:应用层buffer、高性能定时器、对象池
关键指标
- 稳定性
- 熔断、限流、超时控制
- 负载均衡、重试
- 备份请求
- 注册中间件
- 易用性
- 开箱即用
- 周边工具(脚手架、生成代码工具)
- 扩展性
- Middleware
- Option
- 编解码层
- 协议层
- 网络传输层
- 代码生辰工具
- 观测性
- Log、Metric、Tracing
- 内置观测性服务
- 高性能
- 链接池、多路复用、高性能编解码协议、高性能网络库
实践
kitex
Netpoll
- 解决无法感知连接状态问题
- 解决goroutine暴涨问题
- 提升性能
- 调度优化:epoll_wait、gopool
- LinkBuffer:读写并行锁、高效扩缩容、Nocopy Buffer池化
- Pool:引入内存池和对象池
- Codegen:预计算分配内存
- JIT:提升编解码性能
合并部署
微服务过微,传输和序列化开销大,将亲和性强的服务实例尽可能调度到同一个物理机,远程RPC调用优化为本地IPC调用