这是我参与「第五届青训营 」伴学笔记创作活动的第 25 天
1. 基本概念
1.1 本地函数调用
1.1 本地函数调用
**问题:
- 在本地调用中,函数体是直接通过函数指针来指定的,我们调用那个方法,编译器就会自动帮我们调用它相应的函数指针。但是在远程调用中,函数指针是不行的,因为两个进程的地址空间是完全不一样的。所以函数都会有一个自己的ID,使用RPC时附上这个ID,还得有一个ID和函数的关系对照表,通过ID找到对应的函数并执行。
- 客户端如何传递参数给远程服务端函数?在本地调用中,我们只需把参数压到栈里,然后让函数去读即可。但在远程调用中,客户端和服务端是不同的进程,不能通过内存来传递参数。这时候就需要把客户端把参数转换成一个字节流,传递给服务端后,再把字节流转成自己能够读取的格式。
- 网络传输如何高效、稳定?
1.3 RPC概念模型
1984年Nelson发表论文《Implementing Remote Procedure Calls》
1.4 一次RPC的完整过程
- IDL(interface decription language)文件
- IDL通过一种中立的方式来描述接口,使得在不同平台上运行的对象和用不同语言编写的程序可以互相通信
- 生成代码
- 通过编译器工具把IDL文件转换成语言对应的静态库
- 编码器
- 从内存中表示到字节序列的转换称为编码,反之称为解码,也常称作序列化和反序列化
- 通信协议
- 规范了数据在网络中的传输内容和格式。除必须的请求相应参数外,通常还会包含额外的元数据
- 网络传输
- 通常基于成熟的网络库走TCP/UDP传输
1.5 RPC的好处
- 单一职责,有利于分工协作和运维开发
- 可扩展性强,资源利用率更优
- 故障隔离,服务的整体可靠性更高
1.6 RPC带来的问题
- 服务宕机,对方如何处理?
- 在调用过程中网络异常,如何保证消息的可达性?
- 请求量突增导致服务无法及时处理?
2. 分层处理
2.1 分层设计-Apache Thrift例
2.2 编解码层
2.3 编解码层-生成代码
2.4 编解码层-数据格式
- 语言特定的格式
- 好处是非常方便,可以使用很少的额外代码实现内存对象的保存和恢复,这类编码通常跟特定的编程语言深度绑定,其他语言很难读取这种数据。如果以这类编码存储或传输数据,那么就会和这门语言绑死在一起。安全性和兼容性也是问题
- 文本格式
- 文本格式具有人类可读性,数字的编码多有歧义之处,比如XML和CSV不能区分数字和字符串,JSON虽然可以区分但是不能区分整数和浮点数,也不能指定精度,处理大量数据时,问题更严重了;没有强制性的约束,在实际中往往只能采用文档方式来进行约定,这也给调式带来不便之处。由于JSON在一些语言中的序列化和反序列化需要采用反射机制,所以性能比较差
- 二进制编码
- 实现有很多种,TLV编码和Varint编码
2.5 编解码层-TLV编码
2.6 编解码层-选型
2.7 协议层
2.8 协议层-概念
2.9 协议层-协议构造
2.10 协议层-协议解析
2.11 网络通信层
2.12 网络通信层-sockeks API
位于应用层和传输层之间