[rpc框架设计与实现|青训营笔记]

89 阅读4分钟

[rpc框架设计与实现|青训营笔记]
这是我参加「第五届青训营」伴学笔记的第十天

前言
记录青训营后端专场的学习过程,有不足的地方还请大佬指正。
由于本人基础比较薄弱,所以笔记尽可能的详细。

该文章开始的版本将以简述课程知识点为主,等后面实践有自己的理解后会编辑添加自己的理解。


1、rpc基本概念

1.1 通过一个简单的rpc例子引出rpc过程中需要解决的三大问题

如图,在网上商城的应用中,支付服务部署在另一台机器上或者另一个进程中,我们想像在本地或者本进程中调用函数那样调用另一台机器或者另一个进程上的函数。

截屏2023-02-11 15.46.57.png 在远程调用中我们需要解决三个问题:

  • 函数映射问题:比如在该图的例子中,我们如何告诉支付服务我们要调用付款这个函数而不是退款或充值?在本地调用的过程中,函数体是通过函数指针来指定的,我们调用哪个方法,编译器就自动帮我们调用它的函数指针。但是在远程调用过程中,函数指针是不可行的,两个进程的地址空间不一样。解决方法是每个函数都有一个自己的ID,在做rpc的时候附上这个ID,还有这个ID和函数的对照关系,通过ID找到对应的函数并执行。
  • 网络传输问题:在本地调用过程中,我们只需把参数压到栈里,然后让函数自己去栈里读就行。但是在远程调用的过程中是不可行的,客户端和服务端是不同的进程,不能通过内存来传递参数。解决方法就是将客户端把参数转换成一个字节流,传给服务端后,再把字节流转换成自己能读取的格式。
  • 网络传输问题:远程调用往往用在网络上,如何保证网络上高效且稳定的传输数据?

1.2 rpc概念模型

rpc概念模型如下图 截屏2023-02-11 16.04.07.png stub:分布式计算中的stub是一段代码,它转换在远程过程调用期间Client和server之间传递的参数

1.3 一次rpc的完整过程

截屏2023-02-11 16.06.23.png

对右图概念进行解析

IDL出现的必要性:相对于本地函数调用,远程调用的话我们不知道对方有什么方法,以及这个方法的参数等。这个需要一种方式来描述或者说明,这样大家都按照这个约定来调用。这个描述性文件就是IDL。

用户代码和生成代码是一个整体:调用者和被调用者通过约定的规范进行远程调用,双方都依赖同一份IDL文件,通过生成工具来解析IDL描述文件并生成代码,但是在具体调用的时候用户代码又依赖于生成代码(生成代码里封装了编解码网络传输等一系列内容,使用户可以屏蔽底层细节)因此我们可以把用户代码和生成代码看成一个整体

transfer作用:编码仅仅解决了不同(编程)语言中数据交换格式问题。但是在调用者与被调用者的通讯问题中,是否需要制定通讯协议,数据如何传输及网络模型等是transfer要做的事情。

1.4 rpc的好处

  • 单一职责,有利于分工协作和运维开发:开发(采用不同的语言)、部署以及运维(上线独立)都是独立的
  • 可扩展性强,资源利用率高:压力过大的时候可以独立扩充资源,底层基础服务可以复用,节省资源。
  • 故障隔离,服务的整体可靠性提高:某个模块发生故障,不会影响整体的可靠性。

1.5 rpc带来的问题

  • 服务端宕机,客户端如何处理?
  • 调用过程中若发生网络异常,如何保证消息的可达性?
  • 请求量突增导致服务无法及时处理,有哪些应对措施?

RPC框架所采用的分层设计

简述rpc的分层设计

rpc框架的分层设计如下图,从上到下可以看出分别是五层 截屏2023-02-11 16.28.36.png