理论知识
1、什么是RPC?
RPC(Remote Procedure Call),远程过程调用,它是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的协议。
通俗点:
就是说两台服务器A,B,一个应用部署在A服务器上,想要调用B服务器上应用提供的函数/方法,由于不在一个内存空间,不能直接调用,需要通过网络来表达调用的语义和传达调用的数据
2、为什么使用RPC
1.可以做到分布式,现代化的微服务 2.部署灵活 3.解耦服务 4.扩展性强
RPC的目的是让你在本地调用远程的方法,而对你来说这个 调用是透明的,你并不知道这个调用的方法是部署哪里。通过RPC能解耦服务,这才是使用RPC的真正目的。
单台服务器处理能力有限,RPC可提升系统处理能力和吞吐量,也是实现分布式计算的基础。
3、工作原理
首先是client要去调用client stub(存根)这个接口里面的方法,这时候这个接口的实现在远程,所以需要sockets网络传输,才能达到调用(即通过sockets建立连接,传输数据)
但在通过sockets进行传输之前,有一个重要的步骤,需要第2步的序列化(把传输的对象转成可传输的二进制数据)。假设此时server的sockets拿到了数据,需要第4步的反序列化(将拿到的二进制数据反序列化为对象),在这个对象中包含了这个客户端要调用的服务端的信息(像它调用的是那个接口,也即它调用的是哪个存根,接口里面的什么方法, 方法里面参数的类型,以及返回值的类型等)
之后server回去找到这个接口的具体实现类的对象。通常这个对象为了性能考虑,一般会做成单例模式。这个server stub找到这个对象之后会通过反射来调用这个方法,方法调用完成后可以拿到计算的结果
拿到结果后又通过第7步的序列化成二进制,然后通过网络传输8响应给client,client拿到这个数据之后也会通过9将其序列化为对象,然后得到结果10.
那么本次调用结束调用关键点:
- 一定要的网络模块(用于网络传输);
- 序列化模块(对象与二进制数据之间的互转)
- client 端,(怎么就通过调用一个接口就调用到远程方法呢?其实她内部有一个存根代理对象,而这个网络的交互,序列化操作都是由这个代理对象来完成的)
- server端肯定需要一个对服务进行管理的组件,里面完成了服务的查找,服务的反射调用等
附加一张图,帮助理解:
4、RPC解决了什么问题?
- 通讯问题
即A与B之间的通信,建立TCP连接 - 寻址问题
A通过RPC框架连接到B的服务器及特定端口和调用的方法名 - 参数序列化与反序列化
发起远程调用参数值需要二进制化,服务器收到二进制参数需要反序列化
5 技术栈
网络通信这块虽然用的是HTTP,但是对网络通信模块做了一层抽象, 因此可以很方便的换成其它框架.
6、RPC vs HTTP 远程调用方式
常见的远程调用方式有以下几种:
RPC服务
自定义数据格式,基于原生TCP通信,速度快,效率高。
RPC的框架:webservie(cxf)、dubbo
HTTP服务
http其实是一种网络传输协议,基于TCP,规定了数据传输的格式。现在客户端浏览器与服务端通信基本都是采用Http协议。也可以用来进行远程服务调用。缺点是消息封装臃肿。
现在热门的Rest风格,就可以通过http协议来实现。
http的实现技术:HttpClient
两者比较
- 相同点:底层通讯都是基于
socket
,都可以实现远程调用,都可以实现服务调用服务。 - 不同点:
- RPC
- 框架有:dubbo、cxf、(RMI远程方法调用)Hessian
- 当使用RPC框架实现服务间调用的时候,要求服务提供方和服务消费方 都必须使用统一的RPC框架,要么都dubbo,要么都cxf。
- 跨操作系统在同一编程语言内使用
- 优势:调用快、处理快
- HTTP
- 框架有:httpClient
- 当使用http进行服务间调用的时候,无需关注服务提供方使用的编程语言,也无需关注服务消费方使用的编程语言,服务提供方只需要提供restful风格的接口,服务消费方,按照restful的原则,请求服务即可
- 跨系统跨编程语言的远程调用框架
- 优势:通用性强
补充:
- 从传输速度上来看,因为HTTP封装的数据量更多所以数据传输量更大,所以RPC的传输速度是比RESTFUL更快的。
- 因为HTTP协议是各个框架都普遍支持的。
- 在不知道情况来源的框架、数据形势是什么样的,所以在网关可以使用Restful利用http来接受。
- 而在微服务内部的各模块之间因为各协议方案是公司内部自己定的,所以知道各种数据方式,可以使用RPC传输以使各模块之间的数据传输更快。
- 所以可以网关和外界的数据传输使用RESTFUL,微服务内部的各模块之间使用RPC。
- RESTFUL的API的设计上是面向资源的,对于同一资源的获取、传输、修改可以使用GET、POST、PUT来对同一个URL进行区别,而RPC通常把动词直接体现在URL上。
从图上可以看出,二者其实都可以看出在进行实现RPC的时候,底层的通信协议是可以使用HTTP协议的,另外单独的使用HTTP协议也是可以直接的实现调用的功能,理论上,HTTP的请求也是一种方法的调用,通过get或者post方法和url去调用方法,但是HTTP为了更高的可读性将请求头变得非常的臃肿,传输效率比较低,而RPC则是牺牲了可读性使得效率更高。
换句话说其实二者是一种功能,只不过应用的场景不同,而且针对点不同,HTTP是针对Client和Server ;而 RPC是针对 Server 与Server之间的调用,另外RPC之间的调用效率更加的高,而且增加了ZK进行服务的自动配置与管理。
换句话说,上层的协议还是都是依赖于TCP/IP协议,总的来说就是基于字节流来进行编码。
6、交互模式-现有框架对比
服务提供端 Server 向注册中心注册服务,服务消费者 Client 通过注册中心拿到服务相关信息,然后再通过网络请求服务提供端 Server。(注: 注册中心可无.)
直接交互模式中, RPC中, 客户端需要等待服务端返回
常用RPC框架
Dubbo
Dubbo是一个分布式服务框架,致力于提供高性能和透明化的RPC远程服务调用方案
gRPC
是Google开发的高性能、通用的开源RPC框架,其由Google主要面向移动应用开发并基于HTTP/2协议标准而设计,基于ProtoBuf(Protocol Buffers)序列化协议开发,且支持众多开发语言,本身它不是分布式的,所以要实现上面的框架的功能需要进一步的开发。
参考资料
- 【RPC】 ---- RPC入门了解 & 最简单的RPC的实现
- 视频:慕课
- JavaGuide 从零开始手写一个RPC框架。