**这是我参与「第五届青训营 」伴学笔记创作活动的第 12天 **
RPC
本地函数调用
将a和b的值压栈,通过函数指针找到calculate函数,进入函数取出栈中的值2和3,将其赋予x和y,计算x*y,将结果存z,将z的值压栈,然后返回,从栈中取出z赋值给result
rpc
rpc需要解决的问题有函数映射,数据转换成字节流以及网络传输
user-user_stub-network-server_stub-server
IDL文件:IDL通过一种中立的方式来描述接口,使得在不同平台上运行的对象和用不同语言编写的程序可以相互通信
生成代码:通过编译器工具把idl文件转换成语言对应的静态库
编解码:从内存中表示到字节序列的转换称为编码,反之为解码,也常叫做序列化与反序列化。
通信协议:规范了数据在网络中的传输内容和格式。元数据包含
网络传输:基于成熟的网络库走tcp/udp传输
rpc的好处
单一职责,有利于分工协作和运维开发; 可扩展性强,资源使用率更优; 故障隔离,服务的整体可靠性高。
rpc带来的问题
服务宕机;网络异常消息如何可达;服务请求突增,服务处理及时
分层设计
编解码层
考虑兼容性,新增新的字段不影响老的服务;通用性,支持跨平台/跨语言;性能从空间和时间两个维度来考虑,也就是编码后数据大小和编码耗费时长。
协议层
特殊结束符,一个特殊字符作为每个协议单元结束的标示;变长协议,以定长加不定长的部分组成
LENGTH:数据包大小,不包含自身 HEADER MAGUC:标识版本信息,协议解析时候快速校验。 SEQUENCE NUMBER:标识数据包的seqID,可用于多路复用,单连接内递增
网卡通信层
sockets api和网络库
rpc性能
稳定性
熔断:保护调用方,防止被调用的服务出现问题而影响到整个链路 限流:保护被调用方,防止大流量把服务压垮 超时控制:避免资源浪费在不可用节点上。 统称为降级
请求成功率:负载均衡和重试。
长尾请求:put99设置
注册中间件
观测性
Log/Metric/Tracing,内置观测性服务
高性能
连接池/多路服用/高性能编解码协议/高性能网络库
KiteX
自研网络库
解决无法感知连接状态问题,引入epoll主动监听机制,感知连接状态;解决goroutine暴涨的风险,建立goroutine池,复用goroutine;提升性能:引入Nocopy Buffer,向上层提供Nocopy的调用接口,编解码层面零拷贝。
网络库优化
调度优化:epoll_wait在调度上的控制;gopool宠用goroutine降低同时运行协程数 LinkBuffer:读写并行无锁,支持nocopy式流式读写,高效扩缩容,nocopy Buffer 池化,减少gc;pool,引入内存池和对象池,减少gc开销
编解码优化
codegen:预计算并预分配内存,减少内存操作次数,包括内存分配和拷贝。inline减少函数调用次数和不必要的反射操作。
合并部署
亲和性部署,将亲和性强的服务实例调度同一个物理机,中心化的部署调度和流量控制;基于共享内存的通信协议;定制化的服务发现和连接池实现;定制化的服务启动和监听逻辑。