RPC协议介绍

RPC,是Remote Procedure Call的缩写,意为远程过程调用,使得调用远程服务的方法,就像我们调用本地方法一样简单,并且我们不需要关心整个过程底层的细节。

RPC协议被广泛应用于分布式系统节点间的通信,我所接触的分布式存储Curve就广泛使用了RPC协议.

关于RPC协议的实现,有很多RPC框架可以为我们所用,比如gRPC dubbo等,因此我们一般不需要去自己实现RPC

RPC架构

RPC架构.png

整个RPC架构可以看做五个部分:

客户端,调用远程方法 客户端 stub:把客户端调用的方法以及参数等信息传往服务端 网络传输:在客户端stub以及服务端stub之间传递信息,可以是基于TCP也可以是基于UDP 服务端stub:接收客户端的方法调用请求,调用方法,向客户端stub返回执行结果 服务端:提供远程方法

一次RPC调用

一次RPC调用的流程如下:

客户端调用方法(就像调用本地方法一样) 客户端stub将调用的方法及参数信息打包为RpcRequest并序列化 客户端stub得到远程服务地址,将消息发送给服务端 服务端stub接收到消息,反序列化得到RpcRequest,根据RpcRequest中的方法和参数调用本地方法,将得到的结果封装为RpcRequest并序列化 服务端stubRpcResponse响应给客户端stub 客户端stub反序列化消息得到RpcResponce,得到方法调用结果

为什么需要RPC协议?

相信很多第一次接触RPC协议的人,在看完RPC的介绍之后,不禁心生疑惑:这不就是消息传输吗?我已经有了TCP乃至HTTP,不是也可以达到同样的效果吗?那为什么还会有RPC协议并且应用还这么广泛?

我在第一次接触到RPC的时候也有同样的疑惑,并且在很长一段时间里对RPC的理解都比较模糊,那么我们就从TCP说起吧!

众所周知,TCP可以实现可靠的、面向连接的、基于字节流的消息收发,由于是基于字节流的传输,TCP的消息是没有边界的,我们接收和发送的消息就是源源不断的字节流,我们不知道哪些字节流是一个完整的消息,我们可能会收到半个消息也可能会收到一个半消息,想要区分消息的边界就需要我们自己去定义规则来处理,比如传递一个消息时加上消息长度或者加上开始和结束标识,这样我们就可以在源源不断的字节流中区分一个一个完整的消息,我前段时间写了一个Go库tcpack就是用来解决这个问题。

可以看到,纯的TCP通信是不可以直接拿来用的,需要我们在应用层面做相应的处理才可以完美地运行,因此就出现了HTTP websocket等应用层协议,它们都是基于TCP的,提供了更好的封装以支持不同的场景。

大多数的RPC也是基于TCP的,运行在应用层,其实历史上RPC的出现比HTTP更早,HTTP主要处理超文本的传输,并且它是很标准的,因为要确保任何一个浏览器可以向全世界任何一台服务器发起HTTP请求,其请求头中包含了太多的固定的信息,并且使用JSON去序列化结构体数据,相比之下,RPC协议常常用于公司内部微服务之间的通信,它更加灵活,每个公司都可以定制自己的RPC框架,并且可以使用Protobuf这种性能更好的序列化协议去序列化传输数据。

综上所述,RPC性能相比HTTP更好并且实现更灵活,更广泛地应用于微服务以及分布式节点通信场景中。

文章来源:

Author:月梦
link:https://ymiir.netlify.app//分布式/RPC.html