Day 7 Go | 青训营笔记

79 阅读5分钟

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

理解 RPC

RPC 的概念就是远程过程调用。我们本地的函数调用,就是 A 方法调 B 方法,然后得到调用欧冠结果,RPC 就是让你像本地函数调用一样进行跨服务之间的函数调用。互联网发展到现在,我们都在讲微服务,服务都拆分为微服务了,那么相关依赖的调用,就会变成跨服务之间的调用,而他们之间的通信方式就是依靠 RPC。
例如支付服务:
支付服务我们要调用付款这个函数,而不是退款或者充值呢?在本地调用中,函数体是直接通过函数指针来指定的,我们调用哪个方法,编译器就自动帮我们调用它相应的函数指针。但是在远程调用中,函数指针是不行的,因为两个进程的地址空间是完全不一样的。所以函数都有自己的一个ID,在做RPC的时候要附上这个ID,还得有个ID 和函数的对照关系表,通过D找到对应的函数并执行
而客户端把参数值传给远程的函数的过程是:在本地调用中,我们只需要把参数压到栈里,然后让函教自己去找里读就行。但是在远程过程调用时,客户端跟服务端是不同的进程,不能通过内存来传递参 数。这时候就需要客户端把参数先转成一个字节流,传给服务端后,再把字节流转成自己能读取的格式

1-2、RPC 框架的重点

相比本地函数调用,远程调用的话我们不知道对方有哪些方法,以及参数长什么样,所以需要有一种方式来描述或者说声明我有哪些方法,方法的参数都是什么样子的,开发成员可以按照描述文件了解,这个文件就是 IDL 文件。除此之外 从 RPC 基础结构中,有四个重点:

1-2-1、数据序列化

序列化就是将数据结构或对象转换成二进制的过程,也就是编码的过程,序列化后数据才方便进行网络传输;反序列化就是在序列化过程中所生成的二进制转换成数据结构或者对象的过程,将二进制转换为对象后业务才好进行后续的逻辑处理。

常见的序列化协议如下:

  • ProtoBuf(IDL)
  • JSON
  • XML
  • Hessian2

常见的 RPC 框架会支持上述协议中的大部分,尤其是 ProtoBuf 和 JSON 。目前从性能上和使用广泛度上来看,现在一般推荐使用 ProtoBuf,当然很多自研的框架里面他们也会自己实现他们自己的序列化协议。

1-2-2、网络传输(网络通信)

在数据被序列化为二进制后就可以行网络传输了,网络传输就是我们的数据怎么传输到对方服务器上,目前来说,常见的通信传输方式包括 :TCP、UDP、HTTP(HTTP2.0)、QUIC 协议,TCP 是大部分框架都会默认支持的

QUIC(Quick UDP Internet Connection)是谷歌制定的一种互联网传输层协议,它基于UDP传输层协议,同时兼具TCP、TLS、HTTP/2等协议的可靠性与安全性,可以有效减少连接与传输延迟,更好地应对当前传输层与应用层的挑战。QUIC在应用程序层面就能实现不同的拥塞控制算法,这相比于传统的TCP协议,拥有了更好的改造灵活性

1-2-3、RPC 调用方式

网络传输只是数据传输非常基础的一方面,从业务上来看,我们发起一次 RPC 调用,那么还需要 RPC 的调用方式,包括如下三大类:

  • 同步 RPC:最常用的服务调用方式,发起调用请求后同步等待结果,符合我们开发的一贯认知和习惯。开发简单、容易维护、容易理解。

  • 异步 RPC:客户端发起服务调用之后,不同步等待响应,而是注册监听器或者回调函数,待接收到响应之后发起异步回调,驱动业务流程继续执行,实现起来相对复杂,但是高并发场景下性能会更好。

  • 并行 RPC:并行服务调用,一次 I/O 操作,可以发起批量调用,这个并行的批量请求一般是通过协程来实现,然后同步等待响应;

这里需要注意,这个 并行 RPC 和 stream 流式调用是有区别的,流式是说,批量发送请求后,可以不必等所有的消息全收到后才开始响应,而是接收到第一条消息的时候就可以及时的响应。

1-2-4、服务治理

RPC 协议只是定义了 Client 与 Server 之间的点对点调用流程,包括通信协议、RPC 消息解析等部分。但是在实际应用中,远程过程调用的时候还需要考虑服务的路由、负载均衡、高可用等问题,而保障服务之间的调用就需要进行服务治理,服务治理基本就涵盖:服务注册和发现、限流、降级、熔断、重试、失败处理、负载均衡等各种服务治理策略。

一般讲的微服务框架包含了 RPC 框架,微服务体系中最重要的就是 RPC 框架,并且是一般是偏向服务治理的 RPC 框架。微服务需要提供的核心能力包括:微服务架构中通讯的基础协议RPC、服务发现与注册、负载均衡、容错、熔断、限流、降级、权限、全链路日志跟踪
待续。。