RPC 与 REST 对比指南
RPC 可以有很多种,比较流行的是 Alibaba 贡献的 Apache Dubbo、Facebook 贡献的 Apache Thrift 和 Google 的 gRPC。实际上,不同 RPC 框架的底层协议和实现,会有一定的差异,但是也是类同的。为了进一步讨论 RPC。
Thrift 是一种接口描述语言和二进制通信协议,用于定义和创建跨语言的服务。它被当作一个远程过程调用(RPC)框架来使用,是 Facebook 为“大规模跨语言服务”开发的。Thrift 服务在实际应用中分为 4 层,分别是服务器层(server)、处理器层(processor)、数据协议层(protocal)和传输层(transport),它们的作用如下。
服务器层:它提供一个关于 Thrift 的服务器,客户端可以连接它,它会实现一个线程池,来管理这些客户端连接。
处理器层:处理器是由开发者根据自己业务的需要实现的业务逻辑代码。
数据协议层:指定数据采用何种编码协议进行传输,然后客户端也可以按照该协议进行解码解析,还原数据。在 Thrift 中可以使用二进制,这样传输的数据就会大大减少,从而提高传输的速度。当然也可以使用 JSON 类型的数据协议,这样会使得开发者更容易理解。
传输层:可以用 Socket、按帧、压缩(zlib)等协议进行传输。
其中服务层、数据协议层和传输层,Thrift 都已经提供了良好的封装类,我们只需要告诉 Thrift 服务器选择便可以了。而处理器层则是开发所需的业务逻辑代码,需要自行开发。Thrift 的服务调用并不是很复杂。
首先,服务提供者按照 Thrift 的要求提供 4 层结构,然后暴露对应的服务端口。其次,服务消费者会连接服务提供的 Thrift 服务器,获取它暴露的接口的存根(stub),然后通过存根执行远程调用。这里谈到的存根是一个接口,它会屏蔽内部实现的细节,从而提高代码可读性,降低开发者使用的困难。
从 Thrift 来看,可以说,RPC 和 REST 风格服务调用在性能上相差是很大的,究其原因主要是以下 3 点:
RPC 不单可以使用 HTTP 协议,也可以使用其他协议,如 TCP、UDP 等,而 REST 风格只能使用 HTTP 协议。
RPC 需要传递的净荷(payload)小,一般是 REST 风格的 20%左右。而 REST 传输的内容越多,需要的带宽越大、时间也越长,对系统性能不利,因此 RPC 的性能更优。
RPC 一般层级较少,而 REST 风格则需要更多的层结构,这意味着,在转换和传输的性能上,RPC 将大大超过 REST 风格的调用。
注意,以上 3 点只是针对性能来说的。但在分布式(微服务)中,追求的不仅仅是性能,在大部分的情况下,如果不会出现较为严重的性能瓶颈,还是推荐使用 REST 风格,因为 REST 风格比起 RPC,至少有以下 3 种优势:
平台无关性:在 RPC 中,可用协议很多,传输的数据也可以使用不同的规则(如 Java 的序列化数据流),这样就使得它只能适应某些平台。而 REST 风格使用 HTTP 协议,只要约定采用某种数据格式,如 JSON,就具备平台无关性的特点。
安全性:REST 风格遵循的协议多,可以通过防火墙、网关等进行拦截,这样可以降低恶意攻击的可能性。而 RPC 则不具备这样的功能。
独立性:采用 REST 风格后,当前的服务是一个相对独立的服务,对于服务消费者来说,不依赖服务提供者的接口和类。而使用 RPC,则需要服务提供者暴露对应的接口服务进行调用,因此耦合性较高,独立性较差。
从上面可以看出,使用 RPC 可以得到很轻的载荷、传输较轻、速度快、协议层少、转换快,但是会产生依赖性,做不到平台无关性,在安全性上较差。使用 REST 风格,则具备平台无关性、高安全性和独立性。从程序开发的角度来说,使用 REST 风格时,可以把服务提供者看成一个独立的产品,它更容易使用和扩展,依赖性更低,这有利于应用的复用和扩展,可读性也高。如果性能不会遇到严重瓶颈,那么作为开发者,应该先考虑可读性,这就是为什么微服务推荐使用 REST 风格调用,而非 RPC 的原因。对于那些需要高性能、高并发的服务,在某些情况下,也可以考虑牺牲 REST 风格的优点去使用 RPC,以满足性能的需要,所以在使用 RPC 的时候,需要考虑其适用的场景。
版权声明: 本文为 InfoQ 作者【阿泽🧸】的原创文章。
原文链接:【http://xie.infoq.cn/article/470393a9348f9c5e4bb9ac9cb】。
本文遵守【CC-BY 4.0】协议,转载请保留原文出处及本版权声明。
评论