参考:https://www.zhihu.com/question/41609070/answer/1030913797
https://zhuanlan.zhihu.com/p/61364466
RPC(romote procedure call):远程过程调用,它是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的协议。过程其实就是方法。所以PRC可以理解为远程方法调用。
这里的远程调用是相对于本地调用的。
假如你有一个Calculator接口,以及他的实现类CalculatorImpl, 在单体应用中,要调用Calculator的add方法来执行一个加运算,你可以直接调用。这种方法,因为在同一个地址空间,或者在同一块内存,这个称为本地函数调用。
现在系统被改造为分布式应用,接口调用和实现分别在两个子系统中。
服务A中并没有CalculatorImpl这个类,那它要怎么调用服务B的CalculatorImpl的add方法呢?
应用调用另一个应用的解决方案,我们很容易的想到HTTP调用。如要想让服务A调用服务B中的方法,比如让服务B暴露Restful接口,然后让服务A通过这个Restful接口来间接调用CalculatorImpl的方法。
不过,像这种每次调用,都需要些一串发起http请求的代码。能不能去掉这些,像本地调用一样,去发起远程调用,让使用者感知不到远程调用的过程。
怎么实现这个过程呢?
首先,调用方调用的是接口,必须得为接口构造一个假的实现。显然,要使用动态代理。这样,调用方的调用就被动态代理接收到了。
第二,动态代理接收到调用后,应该想办法调用远程的实际实现。这包括下面几步:
- 识别具体要调用的远程方法的IP、端口。
- 将调用方法的入参进行序列化。
- 通过通信将请求发送到远程的方法中。
这样,远程的服务就接收到了调用方的请求。它应该:
- 反序列化各个调用参数
- 定位到实际要调用的方法,然后输入参数,执行方法
- 按照调用的路径返回调用的结果
整个过程如下所示。
从上述的分析我们可以概括地讲,RPC就是让一个应用调用另一个应用中方法的一种实现方法。
它的思路就是:使用代理模式,生成一个代理对象,在这个代理对象的内部,通过httpClient来实现RPC远程调用的过程。
总结一下,RPC要解决的两个问题:
- 解决分布式系统中,服务之间的调用问题。
- 远程调用时,要能够像本地调用一样方便,让调用者感知不到远程调用的逻辑。
这也是很多RPC框架要解决的问题和解决的思路。
在远程调用时,必然要涉及到通信协议选择的问题,其调用协议通常包含传输协议和序列化协议。
传输协议包含: 如著名的 [gRPC](grpc / grpc.io) 使用的 http2 协议,也有如dubbo一类的自定义报文的tcp协议等。
序列化协议包含: 如基于文本编码的 xml json,也有二进制编码的 protobuf hessian等。
当然一个成熟的rpc框架是很全面的,除了通信协议外还有“服务注册发现”,错误重试,服务升级的灰度策略,服务调用的负载均衡等等的实现。
RPC和HTTP的区别是什么?
RPC=Remote Produce Call 是一种技术的概念名词,HTTP是一种协议。它们不是一个层面的东西。
RPC可以通过 HTTP 来实现,也可以通过Socket自己实现一套协议(比如阿里的dubbo)来实现.所以题目可以换一种理解,为何 RPC 还有除 HTTP 之外的实现法,有何必要,毕竟除了HTTP实现外,私有协议不具备通用性。