# 深入浅出RPC框架
远程函数调用(RPC-Remote Procedure Calls)
与本地函数区别:解决函数映射,数据转换成字节流,网络传输。
ILD(Interface description language)文件
IDL通过一种中立的方式来描述接口,是的在不同的平台上运行的对象和用不同语言编写的程序可以相互通信。
生成代码
通过编译器工具把IDL文件转换成语言对应的静态库。
编解码
从内存中表示到字节序列的转换称为编码,反之为解码,也常叫做序列化和反序列化。
通信协议
规范了数据在网络中过得传输内容和格式,除必须的请求/响应数据外,通常还会包含额外的元数据 。
网络传输
通常基于成熟的网络库走TCP/UDP传输。
PRC的好处:1.单一职责,有利于分工协作和运维开发。2可扩展性强。,资源使用率更优。3.故障隔离,服务的整体可靠性高。
弊端在于:1.服务宕机2.调用过程中很难保证信息的可达性3.可求量突增时,如何更有效的利用服务。
分层设计
客户端和服务端依赖于同一份IDL文件,IDL文件通过编码器转化为不同语言的lib代码,文本格式,二进制编码。
二进制编码
TLV编码,Tag:标签,Lenght:长度,Value:值,Value也可以是个TVL结构。
选型: 兼容性,通用性,性能。
协议层
特殊结束符:message body :\r\n。
变长协议: 以不定长和定长的组成,做决定的是定长的。
协议构造:LENGTH 、HEADER MAGIC、 SEQUENCE NUMBER、 HEADER SIZE、PROTOCOL ID、TRANSFORM ID、INRO ID、 PAYLOAD。
网络通信 Sockets API
在TCP/UDP之上,必须知道两个信息,一个端口一个IP。
网络库:
提供易用的API:封装底层Socket api。连接管理和事情分发。
功能:协议支持:TCP,UNP和UDS。
性能:应用层buffer减少copy,高性能定时器,,对象池等。
RPC关键指标分析
1、稳定性:熔断,限流,超时控制。
2、请求成功率:负载均衡,重试。
3、长尾请求:减少长尾请求的延迟。时间减少。
4、注册中间件:使其在一个框架里面,可选的方式。
5、易用性:开箱即用:提供合理测参数,丰富的文档。周边工具:生成代码工具(支持protobuf和thrift一些协议),脚手架工具(生成一些比较重复的代码) 。
6、扩展性:Middleware,Option,编解码层,协议层,网络传输层。代码生成工具插件扩展。
7、观测性:Log(日志)、metric(监控)、tracing(链、路、跟踪,会有一个ID)。 内置观测服务。
8、 高性能:高吞吐,低延迟。
RPC企业实践
背景: 原生库无法感知连接状态,存在gooroutine暴涨风险,连接利用风险低。
Netpoll:引入epoll主动监听机制,感知连接状态。建立goroutine池。 Nocopy Buffer,向上层提供NoCopy的调用接口,编解码层零拷贝。
扩展性设计:支持多协议,也支持灵活的自定义扩展协议。
性能优化:
1、网络库的优化: 调度优化,epoll_wait在调度上的控制,gopoll重用goroutine降低同时运行的协程数。 LinkBuffer 读写并行无锁,支持nocopy地流式读写,高效扩缩容。Poll:引入内存池和对象池,减少GC开销。
2、编解码优化:Codegen:预分配内存,减少操作次数。减少函数调用次数,提高效率。自研了Go语言实现的Thrift IDL解析和代码生成器。 JIT:即时编译,程序加载的阶段,为了改善用户的体验。
合并部署:远程RPC调用优化本地IPC调用,微服务过微,传输和序列化开销越来越大。