这是我参与[第五届青训营]伴学打卡活动的第13天
本地函数调用
例如:
func main(){
var a=2
var b=3
result:=calculate(a,b)
fmt.Println(result)
return
}
func calculate(x,y int){
z:=x*y
return z
}
- 将a和b的值压栈
- 通过函数指针找到calculate函数,进入函数取出栈中的值2和3,将其赋予x和y
- 计算x*y,并将结果存在z
- 将z的值压栈,然后从calculate返回
- 从栈中取出z返回值,并赋值给result
远程函数调用(RPC)
RPC需要解决的问题
- 函数映射
- 数据转换成字节流
- 网络传输
一次完整RPC的完整过程
IDL文件->生成代码->编解码->通信协议->网络传输
RPC的优势
单一职责,有利于分工协作和运维开发
可扩展性强,资源使用率更优
故障隔离,服务的整体可靠性更高
RPC带来的问题
服务宕机,对方应该如何处理? 在调用过程中发生网络异常,如何保证消息的可达性? 请求量突增导致服务无法及时处理,有哪些应对措施?
分层设计
编解码层
Client与Server依赖同一份IDL文件生成不同语言的CodeGen,使用TLV编码。编码层在选型时一般从兼容性(支持自动增加新的字段,而不影响老的服务)通用性(跨平台,跨语言)性能(编码后的数据大小和编码耗费的时长)
协议层
变长协议(定长部分描述不定长部分的内容长度),使用特殊结束符的协议(如string末尾的\r\n)
协议解析流程:Peek->MagicNumber->Peek->PayloadCodec->DecodePayload
网络通信层
Sockets API
网络库:
提供易用API
封装底层Socket API
连接管理和事件分发
功能:
协议支持:tcp,udp和uds等
优雅退出,异常处理
性能:
应用层buffer减少copy
高性能定时器,对象池
总结
RPC框架主要核心有三层:编解码层,协议层和网络通信层
二进制编解码的实现原理和选型要点
协议的一般构造,以及框架协议解析的基本流程
Socket API的调用流程,以及选型网络库时要考察的核心指标