HTTP协议,以其中的Restful规范为代表,它可读性好,且可以得到防火墙的支持、跨语言的支持。Restful优势很大,大有超过RPC的趋势。

但是HTTP也有其缺点,这是与其优点相对应的。首先是有用信息占比少,毕竟HTTP工作在第七层,包含了大量的HTTP头等信息。其次是效率低,还是因为第七层的缘故。还有,其可读性似乎没有必要,因为我们可以引入网关增加可读性。此外,使用HTTP协议调用远程方法比较复杂,要封装各种参数名和参数值。

而RPC则与HTTP互补,RPC的全称是Remote Procedure Call,中文叫“远程过程调用”。过程其实就是方法。所以,可以把RPC理解为“远程方法调用”。它其实就是让一个应用调用另一个应用中方法的一种实现方式

而在分布式系统中,因为每个服务的边界都很小,很有可能调用别的服务提供的方法。这就出现了服务A调用服务B中方法的需求,即远程过程调用。

要想让服务A调用服务B中的方法,最先想到的就是通过HTTP请求实现。是的,这是很常见的,例如服务B暴露Restful接口,然后让服务A调用它的接口。基于Restful的调用方式因为可读性好(服务B暴露出的是Restful接口,可读性当然好)而且HTTP请求可以通过各种防火墙,因此非常不错。

然而,如前面所述,基于Restful的远程过程调用有着明显的缺点,主要是效率低、封装调用复杂。当存在大量的服务间调用时,这些缺点变得更为突出。

服务A调用服务B的过程是应用间的内部过程,牺牲可读性提升效率、易用性是可取的。基于这种思路,RPC产生了。

通常,RPC要求在调用方中放置被调用的方法的接口。**调用方只要调用了这些接口,就相当于调用了被调用方的实际方法,十分易用。**于是,调用方可以像调用内部接口一样调用远程的方法,而不用封装参数名和参数值等操作。

那要想实现这个过程该怎么办呢?
首先,调用方调用的是接口,必须得为接口构造一个假的实现。显然,要使用动态代理。这样,调用方的调用就被动态代理接收到了。

第二,动态代理接收到调用后,应该想办法调用远程的实际实现。这包括下面几步:
• 识别具体要调用的远程方法的IP、端口
• 将调用方法的入参进行序列化
• 通过通信将请求发送到远程的方法中

这样,远程的服务就接收到了调用方的请求。它应该:
• 反序列化各个调用参数
• 定位到实际要调用的方法,然后输入参数,执行方法
• 按照调用的路径返回调用的结果
调用方调用内部的一个方法,但是被RPC框架偷梁换柱为远程的一个方法。之间的通信数据可读性不需要好,只需要RPC框架能读懂即可,因此效率可以更高。通常使用UDP或者TCP作为通讯协议,当然也可以使用HTTP。

最后说一句,不是说RPC好,也不是说HTTP好,两者各有千秋。本质上,两者是可读性和效率之间的抉择,通用性和易用性之间的抉择。 最终谁能发展更好,很难说。到底应该选哪个,我建议根据业务场景,灵活站位……