为什么要使用RPC框架
RPC(Remote Procedure Call)—远程过程调用,它是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的协议。比如两个不同的服务 A、B 部署在两台不同的机器上,那么服务 A 如果想要调用服务 B 中的某个方法该怎么办呢?使用 HTTP请求 当然可以,但是可能会比较慢而且一些优化做的并不好。 RPC 的出现就是为了解决这个问题。
- RPC网络模型对于是透明的。即调用者不需要关注传输层协议使用的是UDP还是TCP,也不关注网络IO的模型。
- RPC服务提供协议式的消息通信机制,即通信双方使用proto或者thrift规定好传输的信息,调用方正确地将信息传递到接收方(Request),就可以实现一次通信,通信的结果通过Response返回。
- 跨语言的能力:在企业中,经常可以听到XX引擎,比如:翻译引擎,这个引擎有可能使用python去做的,然后暴露一个RPC接口。调用方有可能使用的是Java,也有可能是Go又或者是NodeJs,但是翻译引擎并不关心。只要翻译引擎正确接受到了信息,就可以进行处理。因为在传输过程中,消息都会被序列化,所以在这一层面上就摆脱了变成语言的束缚。
RPC框架如何实现通信
- client为服务的调用方,通常我们写好thrift文件之后,使用kite框架能够自动生成调用的框架。
- Server为服务的提供方通常在kite生成了接口之后,程序员需要实现对应的接口来完成RPC服务。调用方并不关心服务方具体实现,只需要通过接口获取想要的数据。
- RPC Proxy存在于客户端,客户端对RPC框架是透明调用的,客户端无法自行管理消息格式、网络协议,也不能判断调用过程是否出现了异常,这些工作都是由代理层去实现的。
- Message Protocol:通信双方约定的一种通信协议(消息格式),专门对网络传输承载的信息进行编码和解码操作。
- NetWork Protocol:RPC基于的网络协议,可以是基于应用层的HTTP也可以是基于传输层的TCP,不同的RPC框架基于不同的网络协议。
- RPC Processor:服务端的业务层并不知道自己的服务会被一个RPC Client调用,所以在RPC框架中应该有一种负责执行RPC接口是心啊的工具,包括管理RPC接口的注册、判断客户端请求权限,控制借口实现类执行等各种工作
- IDL文件,跨语言的RPC必须提供一种统一的消息格式、接口描述形式,这些定义都需要包含在IDL文件中。
RPC的调用过程可以同下图进行描述:
影响RPC框架性能的因素
- 使用的网络IO模型
一般的RPC服务都是基于同步阻塞的IO模型,也可以做一些改进让RPC服务器能够实现非阻塞同步或者多路IO模型的支持,可以提高单位时间内处理RPC请求的数量,也可以提高CPU资源的利用率。 - 基于的网络协议
RPC可以工作在应用层也可以工作在传输层协议上,工作在哪一层对于RPC框架的性能最终并没有多大的影响;但从目前主流的RPC框架来看,没有使用UDP作为网络传输协议的。 - 消息封装的格式
消息的封装格式需要考虑的问题包括:- 消息的易读性:Clean Code中有提出使用规范的编码来替代代码中的注释。
- 描述内容时消息的大小:需要考虑TCP粘包/半包的问题。
市面上几种RPC框架的对比。
RMI(JDK自带): JDK自带的RPC,有很多局限性,不推荐使用。
Dubbo: Dubbo是 阿里巴巴公司开源的一个高性能优秀的服务框架,使得应用可通过高性能的 RPC 实现服务的输出和输入功能,可以和 Spring框架无缝集成。目前 Dubbo 已经成为 Spring Cloud Alibaba 中的官方组件。
gRPC :gRPC是可以在任何环境中运行的现代开源高性能RPC框架。它可以通过可插拔的支持来有效地连接数据中心内和跨数据中心的服务,以实现负载平衡,跟踪,运行状况检查和身份验证。它也适用于分布式计算的最后一英里,以将设备,移动应用程序和浏览器连接到后端服务。
Hessian: Hessian是一个轻量级的remotingonhttp工具,使用简单的方法提供了RMI的功能。 相比WebService,Hessian更简单、快捷。采用的是二进制RPC协议,因为采用的是二进制协议,所以它很适合于发送二进制数据。
Thrift: Apache Thrift是Facebook开源的跨语言的RPC通信框架,目前已经捐献给Apache基金会管理,由于其跨语言特性和出色的性能,在很多互联网公司得到应用,有能力的公司甚至会基于thrift研发一套分布式服务框架,增加诸如服务注册、服务发现等功能。