Day12-深入浅出RPC框架1 | 青训营笔记

56 阅读3分钟

“这是我参与「第五届青训营 」伴学笔记创作活动的第 12 天”

1.1 RPC基本概念

1.1.1 本地函数调用

  • 本地调用的参数在内存栈中压入栈;

  • 如果inline,甚至不需要调用call;(通过函数指针即可)

image.png

1.1.2 远程函数调用(RPC Remote Procedure Calls)

  • 不同服务器之间的远程函数调用
  • 存在问题:

  • 1)函数映射

  • 不能使用函数指针调用,因为两个进程的地址空间完全不同;

  • 解决:每个函数有ID,RPC要附上ID,并且有ID与函数的对照关系表;完成函数映射;

  • 2)远程传递参数

  • 本地调用,只需参数压入栈,但远程调用,client和server在不同服务器,不能通过内存传递参数;

  • 解决:数据转换为字节流(编解码);

  • 3)网络传输的高效稳定

image.png

1.1.3 RPC概念模型

image.png

1.1.4 一次RPC的完整过程

  • 1)IDL文件:中立语言描述接口(因为可能不同服务采用不同语言,C++,go,java);
  • 2)生成代码:通过编译器工具把IDL文件转化为语言对应的静态库;
  • 3)编解码;
  • 4)通信协议;
  • 5)网络传输;

image.png

1.1.5 RPC的好处

  • 2.例如压力过大时,可以针对性独立扩充资源,底层基础服务可以复用,节省资源;

image.png

1.1.6 RPC带来的问题

  • RPC带来好处的同时也带来不少新的问题,将由RPC框架里解决;

image.png

1.1.7 小结

image.png

1.2 RPC框架分层设计

1.2.1 以Apache Thrift框架为例

  • 1)编解码层;(合并有IDL生成)
  • 2)协议层;
  • 3)网络通信层;

image.png

1.2.2 编解码层

image.png

1、编解码层-生成代码

image.png

2、编解码层-数据格式

  • 1)语言特定格式
  • 缺点:兼容性和安全性不好;好处:可以用很少的额外代码实现内存的保存和恢复;
  • 2)文本格式:
  • 文本格式:文本格式具有人类可读性,数字的编码多有歧义之处,比如XML和CSV不能区分数字和字符串,JSON虽然区分字符串和数字,但是不区分整数和浮点数,而且不能指定精度,处理大量数据时,这个问题更严重了﹔没有强制模型约束,实际操作中往往只能采用文档方式来进行约定,这可能会给调试带来一些不便。由于JSON在一些语言中的序列化和反序列化需要采用反射机制,所以在性能比较差;
  • 3)二进制编码
  • 实现有很多种,例如TLV编码和Varint编码;

image.png

3、编解码层-二进制编码(TLV编码)

  • TLV编码结构简单清晰,并且扩展性好,但是由于增加了type和length两个冗余信息,有额外内存开销,特别是在大部分字段都是基本类型的情况下有不小的空间浪费;

image.png

image.png

4、编解码层-选型

image.png

1.2.3 协议层

image.png

1、协议层-概念

image.png

2、协议层-协议构造

image.png

3、协议层-协议解析

image.png

1.2.4 网络通信层

image.png

1、网络通信层-sockets API

  • 套接字编程中客户端必须知道两个信息:服务端IP地址,端口号
  • listen监听进来的连接,其中有一个backlog参数,为半连接队列的最大数量,linux中默认为128;
  • read和write在socket中默认阻塞;
  • socket关闭套接字,当另一端socket关闭后,这一端读写的情况:尝试去读会得到一个EOF,并返回0. 尝试去写会触发一个SIGPIPE信号,并返回-1和errno=EPIPE,SIGPIPE的默认行为是终止程序,所以通常我们应该忽略这个信号,避兔程序终止。

image.png

2、网络通信层-网络库

image.png

1.2.5 小结

image.png