什么是RPC
RPC(Remote Procedure Call)远程过程调用,简单的理解是一个节点请求另一个节点提供的服务。是一种进程间的通信方式,它允许应用程序调用网络上的另一个应用程序中的方法,对于服务的消费者而言,无需了解远程调用的底层细节,是透明的,需要注意的是RPC并不是一个具体的技术,而是指整个网络远程调用过程。
RPC远程过程调用,是分布式架构的核心,按响应方式分如下两种:
- 同步调用:客户端调用服务方方法,等待直到服务方返回结果或者超时,再继续自己的操作。
- 异步调用:客户端把消息发送给中间件,不再等待服务端返回,直接继续自己的操作。
RPC原理
RPC过程
简单来说一个RPC架构里包含如下4个组件:
- 客户端(Client):服务调用者
- 客户端存根(Client Stub):存放服务端地址信息,将客户端的请求参数打包成网络消息,再通过网络发送给服务方
- 服务端存根(Server Stub):接受客户端发送过来的消息并解包,再调用本地服务
- 服务端(Server):服务提供者。
- 服务调用方(client)调用以本地调用方式调用服务;
- client stub接收到调用后负责将方法、参数等组装成能够进行网络传输的消息体(序列化的过程)
- client stub找到服务地址,并将消息通过网络发送到服务端;
- server stub收到消息后进行解码(反序列化的过程)
- server stub根据解码结果调用本地的服务;
- 本地服务执行处理逻辑;
- 本地服务将结果返回给server stub;
- server stub将返回结果打包成消息(序列化的过程)
- server stub将打包后的消息通过网络并发送至消费方;
- client stub接收到消息,并进行解码 (反序列化的过程)
- 服务调用方(client)得到最终结果
序列化是可以选择的,不一定要采用json,还可以使用xml、xml、prorobuf、msgpack
网络传输
远程调用往往用在网络上,客户端和服务端是通过网络连接的。所有的数据都需要通过网络传输,因此就需要有一个网络传输层。网络传输层需要把序列化后的参数字节流传给服务端,然后再把序列化后的调用结果传回客户端。只要能完成这两者的,都可以作为传输层使用。因此,它所使用的协议其实是不限的,能完成传输就行。尽管大部分RPC框架都使用TCP协议,但其实UDP也可以,而gRPC干脆就用了HTTP2。Java的Netty也属于这层的东西。
小结
本文只是简单介绍了RPC中的序列化和网络传输,其实RPC本身是一个很大的话题,除了序列化反序列化和网络传输以外还需要更多的细节:比如如何保证在不可靠的网络中保证RPC的可靠性?如何实现客户端的重试调用、超时控制?如何优雅的起停服务、发现与注册服务?网络错误、流量控制、等还有很多问题值得大家研究学习,这里不做过多探讨了。
|