什么是 RPC

什么是 RPC

RPC(Remote Procedure Call)远程过程调用,它是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的协议。下面举个简单的例子来理解 RPC。 远程过程调用相对应的就是本地过程调用。打个比方,你在家里,要洗衣服,你直接把衣服放到洗衣机,开启洗衣机开关,这就是本地过程调用。远程调用就是,你不在家里,你打个电话回家里,跟妈说帮忙洗个衣服,这就是远程调用。

RPC

二、RPC

通过前言,大家简单理解了下 RPC。下面,我们将从计算机的角度来理解 RPC。 在互联网架构演进中,我们提到过互联网架构先后经历了单体架构、集群架构、分布式架构、SOA、微服务架构、服务网格。在系统还是单体架构时,所有的调用都是在同一台设备中的,这就像前言说的“在家里”,也就是本地过程调用。而到了分布式时代,这一切发生了变化,服务与服务之间的调用逐渐增多,而我们更希望调用另外一个服务就跟本地调用一样,RPC 就这样产生了。 下面还用洗衣服的例子来详细说明下 RPC。 假如有一个家务接口 Housework,以及它的实现类 HouseworkImpl,在单体架构中,你要调用 Housework 来执行洗衣服,直接 new 一个 HouseworkImpl,然后调用 washingClothes 方法就行了,这其实就是本地过程调用,因为在同一个地址空间,或者说在同一块内存,所以通过方法栈和参数栈就可以实现。

RPC

随着家里的人口越来越多,衣服量越来越大,这个时候发现一个 HouseworkImpl 是洗不过来的,于是你决定把 HouseworkImpl 单独拎出来。

RPC

这时候你发现,不但能处理高并发(多搞几个 HouseworkImpl),而且 HouseworkImpl 还可以共享给家人了,达到了代码复用,服务复用,这也就是分布式想达到的高性能和高可靠。这一切看似非常完美,但是 main 要怎么调动到 HouseworkImpl 服务呢? 当然,可以使用 B/S 架构,在 HouseworkImpl 服务中暴露一个 RESTful 接口,然后 main 服务通过调用这个接口来间接调用 washingClothes 方法。但这样每次调用的时候还需要写一串发起 http 请求的代码,这不太麻烦了吗?有没有办法像本地调用一样,去发起远程调用,让使用者感知不到远程调用的过程呢?类似下面这样:

1
2
3
4
5
@Remote
private Housework housework;
...
housework.washingClothes()
...

也许你想到了,用代理模式呀!扫描到 @Remote 注解,就生成一个代理对象,将这个代理对象放进容器中。而这个代理对象的内部,就是通过 httpClient 来实现远程过程调用。 虽然上面的描述比较抽象,不过这就是很多 RPC 框架要解决的问题和解决的思路,比如 Dubbo。 由以上例子可看出 RPC 要解决的两个问题:

  • 解决分布式系统中,服务之间的调用问题。
  • 远程调用时,要能够像本地调用一样方便,让调用者感知不到远程调用的逻辑。

三、实现 RPC

大家一定会想说用上面说的 HTTP 暴露一个 RESTful 接口就可以了。但实际上,RPC 只是想传输一下数据而已,不必动用到一个文本传输的应用层协议。我们可以直接使用二进制传输(比如 Socket),或者像 gRPC 一样,使用 HTTP2.0

无论是何种协议进行数据传输,一个完整的 RPC 过程,都可用下图来描述:

RPC

  • Client 就是 RPC 的调用方
  • Client Stub 就是我们上面说到的代理对象,也就是那个看起来像是 Housework 的实现类,其实内部是通过 RPC 方式来进行远程调用的代理对象,
  • RPC Runtime,则是实现远程调用的工具包,比如 HTTP2.0,最后通过底层网络实现实现数据的传输。

这个过程中最重要的就是序列化和反序列化了,因为数据传输的数据包必须是二进制的,Client 丢一个对象过去,Server 可不认识,你必须把对象序列化为二进制格式,传给 Server 端,Server 端接收到之后,再反序列化为对象。

四、小结

本文先通过洗衣服的例子帮助大家理解 RPC 的概念,再从计算机的角度解释了 RPC,最后讲了下 RPC 实现的流程,希望能帮助大家理解 RPC。

Rating: