聊今天的话题之前,先普及个关于网络架构的分层的知识,在当前的世界中,有两套网络的参考模型,一套是 OSI 参考模型,一套是 TCP/IP 的参考模型。对于 java 开发而言,我们只需要知道现在用的是 TCP/IP 模型,这个模型分为四层就可以了。
OSI 参考模型(Open Systems Interconnection Reference Model):包括七层,这个模型过于理想化,未能在因特网中进行广泛推广。
TCP/IP 参考模型:包括四层,事实上的国际标准。
我们经常使用的 REST API 是基于 HTTP 协议来传输数据的,而 RPC 主要是基于 TCP/IP 协议的,所以效率来看的话,RPC 的效率会高一点,毕竟是在传输层;尤其是在复杂的系统中使用 RPC 效果会更明显。
restful 是一种网络应用程序的设计风格和开发方式,基于 http 实现,可以使用 xml 格式定义或 json 格式定义。restful 适用于移动互联网厂商作为业务使能接口的场景,实现第三方 ott 调用移动网络资源的功能,动作类型为查询、新增、变更和删除所调用的资源。
REST 是 Representational State Transfer 的缩写,是基于 http 协议之上的一组约束和属性,翻译过来是表现层状态转移。
REST 是一种设计风格(并非一种标准),描述的是在网络中 Client 和 Server 的一种交互形式,目的是便于不同的软件/程序在网络中互相传递消息。
REST 充分利用 HTTP 自身的 GET、POST、PUT、DELETE 的方法实现接口的统一化,比如对一个资源进行 CURD 的操作,如下所示:
GET url/user 获取所有用户
POST url/user 新增/修改用户信息
PUT url/user 修改用户信息
DELETE url/user 删除用户信息
REST API 主要的设计原则:资源与URI、统一资源接口(HTTP方法如GET,PUT和POST)、资源的表述、资源的链接、状态的转移 。
REST API 大概由以下三部分组成:
method:动词(GET,POST之类的)。
Host/post:URI(统一资源标识)、服务器,端口。
Path:名词(路径,服务器里面的某个东西)路径的结尾是资源的形态(如 text,html, image, pdf 等)。
REST API 常见的 HTTP code 如下:
Status Code:200 表示请求成功(OK)。
Status Code:400 表示请求错误 (Bed Request)。
Status Code:404 表示未发现服务(Not Found)。
Status Code:500 表示服务器内部错误(Internal Server Error)。
总之,RESTFUL 的核心就是后端将资源发布为 URI ,前端通过 URI 访问资源,并通过 HTTP 动词表示要对资源进行的操作。
RPC (Remote Procedure Call),远程过程调用,就是从一台机器(客户端)上通过参数传递的方式调用另一台机器(服务器)上的一个函数或方法(可以统称为服务)并得到返回的结果。
RPC 在使用形式上像调用本地函数(或方法)一样去调用远程的函数(或方法)。通常的调用过程是把函数序列化,远端收到后,再把函数反序列化,完成函数调用。
一个完整的 RPC 的架构应该包含以下几个组件:
客户端(Client):服务的调用方。
服务端(Server):真正的服务提供者。
Client stub:存放服务端的地址消息,再将客户端的请求参数打包成网络消息,然后通过网络远程发送给服务方。
Server stub:接收客户端发送过来的消息,将消息解包,并调用本地的方法。
RPC 采用 Client-Server 结构,通过 request-response 消息模式实现。
在实际开发的情况下,RPC 很少用到 http 协议来进行数据传输,毕竟只是想传输一下数据而已,何必动用到一个文本传输的应用层协议呢。为什么不直接使用二进制传输?比如直接用 Java 的 Socket 协议进行传输?
不管用何种协议进行数据传输,一个完整的 RPC 过程,都可以用下面这张图来描述:
1、Client 是服务调用方,Server 是服务提供者。
2、左边的 Client 里的 Application 就是一个真正的调用者,先去调用 Client Stub 这个代理对象,其实内部是通过 RPC 方式来进行远程调用的代理对象,这一步主要是来传递参数。
3、至于 Client Runtime Library,则是实现远程调用的工具包,比如 jdk 的 Socket。最后通过底层网络实现实现数据的传输。
4、客户端本地操作系统将消息从客户端机器发送到服务端机器。
5、服务端操作系统接收到数据包传递给 Server Stub。
6、Server Stub 解组消息为参数。
7、Server Stub 再调用服务端的函数(或方法),得到执行结果之后以反方向的相同的步骤响应给客户端,至此就完成了一次 RPC 调用。
在这个过程中最重要的就是 序列化 和 反序列化 了。因为数据传输的数据包必须是二进制的,直接丢一个 Java 对象过去,人家可不认识,必须把 Java 对象序列化为二进制格式,传给 Server端,Server 端接收到之后,再反序列化为 Java 对象。
REST API :主要为第三方暴露接口,比如暴露给 APP 端,WEB 端。
RPC:主要在自家比较复杂的业务系统中使用,完成服务之间的通信。