-
RPC概念模型:User、User-Stub、RPC-Runtime、Server-Stub、Server
-
相比本地函数调用,RPC调用需要解决的问题:函数映射、数据转换成字节流、网络传输
-
RPC框架分层设计:
编解码层:生成代码和编解码层相互依赖,框架的编解码应当具备扩展任意编解码协议的能力。
数据格式:语言特定格式、文本格式、二进制编码
考察:兼容性、通用性、性能(空间开销、时间开销)
传输协议层
网络通信层:网络库的核心功能就是去同时监听大量的文件描述符的状态变化,并对于不同状态变更,安全高效地进行对应的文件操作。
阻塞 IO 下,耗费一个线程去阻塞在 read(fd) 去等待用足够多的数据可读并返回。浪费线程(会占用内存和上下文切换开销)
非阻塞 IO 下,不停对所有 fds 轮询 read(fd) ,如果读取到 n <= 0 则下一个循环继续轮询。浪费 CPU 做大量无效工作
基于 IO 多路复用系统调用实现的 Poll 的意义在于将可读/可写状态通知和实际文件操作分开,并支持多个文件描述符通过一个系统调用监听以提升性能。
-
RPC框架的核心指标:
稳定性:保障策略:熔断、限流、超时(三种均服务降级)
请求成功率:负载均衡、重试
长尾请求:BackupRequest
易用性:开箱即用(合理的默认参数选择、丰富的文档)、周边工具(生成代码工具、脚手架工具)
扩展性:Middleware:构造成一个有序调用链逐个执行
Option:作为初始化参数
核心层支持扩展
代码生成工具也支持插件扩展
观测性:Log、Metric、Tracing
内置观测性服务:用于观察框架内部状态(当前环境变量、配置参数、缓存信息、内置pprof服务用于排查问题)
高性能:连接池和多路复用:复用连接,减少频繁建联带来的开销
高性能编解码协议:thrift、protobuf、flatbuffer等
高性能网络库:netpoll和netty等
-
自研网络库netpoll,背景:原生库无法感知连接状态;原生库存在goroutine暴涨的风险
-
网络优化:调度优化;LinkBuffer减少内存拷贝,从而减少GC;引入内存池和对象池
-
编解码优化:Codegen:预计算提前分配内存,inline,SIMD等
JIT:无生产代码,将编译过程移到了程序的加载(或首次解析)阶段,可以一次性编译生成对应的codec并高效执行
-
合并部署:微服务过微,引入的额外的传输和序列化开销越来越大
将强依赖的服务统计部署,有效减少资源消耗