网络通信协议

`RPC`,是`Remote Procedure Call`的缩写,意为远程过程调用,使得调用远程服务的方法,就像我们调用本地方法一样简单,并且我们不需要关心整个过程底层的细节。 `RPC`协议被广泛应用于分布式系统节点间的通信,我所接触的分布式存储`Curve`就广泛使用了`RPC`协议. 关于`RPC`协议的实现,有很多RPC框架可以为我们所用,比如`gRPC` `dubbo`等,因此我们一般不需要去自己实现`RPC`。 ## RPC架构 [![RPC架构.png](https://z1.ax1x.com/2023/12/10/piRde7n.png)](https://imgse.com/i/piRde7n) 整个`RPC`架构可以看做五个部分: 1. 客户端,调用远程方法 2. 客户端 `stub`:把客户端调用的方法以及参数等信息传往服务端 3. 网络传输:在客户端`stub`以及服务端`stub`之间传递信息,可以是基于TCP也可以是基于UDP 4. 服务端`stub`:接收客户端的方法调用请求,调用方法,向客户端`stub`返回执行结果 5. 服务端:提供远程方法 ### 一次RPC调用 一次`RPC`调用的流程如下: 1. 客户端调用方法(就像调用本地方法一样) 2. 客户端`stub`将调用的方法及参数信息打包为`RpcRequest`并序列化 3. 客户端`stub`得到远程服务地址,将消息发送给服务端 4. 服务端`stub`接收到消息,反序列化得到`RpcRequest`,根据`RpcRequest`中的方法和参数调用本地方法,将得到的结果封装为`RpcRequest`并序列化 5. 服务端`stub`将`RpcResponse`响应给客户端`stub` 6. 客户端`stub`反序列化消息得到`RpcResponce`,得到方法调用结果 ## 为什么需要RPC协议? 相信很多第一次接触`RPC`协议的人,在看完`RPC`的介绍之后,不禁心生疑惑:这不就是消息传输吗?我已经有了`TCP`乃至`HTTP`,不是也可以达到同样的效果吗?那为什么还会有`RPC`协议并且应用还这么广泛? 我在第一次接触到`RPC`的时候也有同样的疑惑,并且在很长一段时间里对`RPC`的理解都比较模糊,那么我们就从`TCP`说起吧! 众所周知,`TCP`可以实现可靠的、面向连接的、基于字节流的消息收发,由于是基于字节流的传输,`TCP`的消息是没有边界的,我们接收和发送的消息就是源源不断的字节流,我们不知道哪些字节流是一个完整的消息,我们可能会收到半个消息也可能会收到一个半消息,想要区分消息的边界就需要我们自己去定义规则来处理,比如传递一个消息时加上消息长度或者加上开始和结束标识,这样我们就可以在源源不断的字节流中区分一个一个完整的消息,我前段时间写了一个`Go`库[tcpack](https://github.com/lim-yoona/tcpack)就是用来解决这个问题。 可以看到,纯的`TCP`通信是不可以直接拿来用的,需要我们在应用层面做相应的处理才可以完美地运行,因此就出现了`HTTP` `websocket`等应用层协议,它们都是基于`TCP`的,提供了更好的封装以支持不同的场景。 大多数的`RPC`也是基于`TCP`的,运行在应用层,其实历史上`RPC`的出现比`HTTP`更早,`HTTP`主要处理超文本的传输,并且它是很标准的,因为要确保任何一个浏览器可以向全世界任何一台服务器发起`HTTP`请求,其请求头中包含了太多的固定的信息,并且使用`JSON`去序列化结构体数据,相比之下,`RPC`协议常常用于公司内部微服务之间的通信,它更加灵活,每个公司都可以定制自己的`RPC`框架,并且可以使用`Protobuf`这种性能更好的序列化协议去序列化传输数据。 综上所述,`RPC`性能相比`HTTP`更好并且实现更灵活,更广泛地应用于微服务以及分布式节点通信场景中。

版权声明: 如无特别声明,本文版权归 月梦の技术博客 所有,转载请注明本文链接。

(采用 CC BY-NC-SA 4.0 许可协议进行授权)

本文标题:《 RPC协议介绍 》

本文链接:https://ymiir.netlify.app//draft/2023-12-10-RPC

本文最后一次更新为 天前,文章中的某些内容可能已过时!