RPC前景索引
- 本地函数调用
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(Remote Procedure Calls)远程函数调用,我们可以知道他是通过有一定距离的远程调用,所以RPC需要解决的问题有:函数映射、数据转换成字节流、网络传输。
一次完整的RPC过程
- IDL文件:IDL通过一种中立的方式来描述接口,使得在不同平台上运行的对象和用不同语言编写的程序可以相互通信
- 生成代码:通过编译器工具把IDL文件转换成语言对应的静态库
- 编译码:从内存中表示字节序列的转换称为编码,反之为解码,也常叫做序列化和反序列化
- 通信协议:规范了数据在网络中的传输内容和格式。除必须得请求/响应数据外,通常还会包含额外的元数据
- 网络数据:通常基于成熟的网络库走TCP/UDP传输。
RPC好处
- 单一职责,有利于分工协作和运维开发
- 可扩展性强,资源使用率更优
- 故障隔离,服务的整体可靠性更高,不会引起整体服务崩溃
RPC带来的问题
- 服务宕机,对方如何处理
- 在调用过程中发生网络异常,然后消除信息可达性
- 请求量突增导致服务无法及时处理,有哪些措施
而以上这些问题就能够引出后续所说RPC框架。
RPC框架(分层设计)
- 用户自己编写的业务逻辑代码
- 通过代码生成工具把IDL文件转换成不同语言对应的lib代码,里面封装了编解码逻辑
- 框架的编解码层
- 框架的协议层
- 框架的网络通信层
编译码层
1)数据格式
- 语言特定格式:许多编程语言都内建了将内存对象编码为字节序列的支持
- 文字格式:JSON、XML、CSV等文字格式,具有人类可读性,但其中也含有一些缺陷
- 二进制编码:具备跨语言和高性能等优点,常见有Thrift的BinaryProtocol。
2)二进制编码 其中包含TLV编码(减少数据描述的代码,简洁清晰,拓展性比较好)
3)选型
- 兼容性:支持自动增加新的字段,而不影响老的服务,这将提高系统的灵活度
- 通用性:支持跨平台、跨语言
- 性能:从空间和时间两个维度考虑,也就是编码后数据大小和编码耗费时长,性能高的话可能造成性能膨胀。
协议层
1)概念: 特殊结束符:一个特殊的字符作为每个协议单元结束的标示 变长协议:以定长加不定长的部分组成,其中定长部分需要描述不定长的内容长度
2)协议构造:
- LENGTH : 数据包大小,不包含自身
- HEADER MAGIC : 标识版本信息,协议解析时候快速校验
- SEQUENCE NUMBER: 表示数据包的seqID,可用于多路复用,单连接内递增
- HEADER SIZE : 头部长度,从第14字节开始计算一直到PLAYLOAD 前
- PROTOCOL ID : 编解码方式,有Binary和Compact两种
- TRANSFORM ID : 压缩方式,如zlib
- INFO ID : 传递一些定制的mate信息
- PAYLOAD :消息体
网络通信层(Sockets API)
网络库:提供易用API、功能(协议支持,优雅退出、异常处理)、性能(应用层buffer减少copy,高性能定时器、对象池)
总结
RPC主要核心有三层:编解码层、协议层和网络通信层,而以上我相对简易介绍了三个层的相关知识点,以上仅供参考。