定义
RPC(Remote Procedure Call) 即远程过程调用,通过名字我们就能看出 RPC 关注的是远程调用而非本地调用。
为什么要 RPC ?
因为,两个不同的服务器上的服务提供的方法不在一个内存空间,所以,需要通过网络编程才能传递方法调用所需要的参数。并且,方法调用的结果也需要通过网络编程来接收。但是,如果我们自己手动网络编程来实现这个调用过程的话工作量是非常大的,因为,我们需要考虑底层传输方式(TCP 还是 UDP)、序列化方式等等方面。RPC 能帮助我们做什么呢?
简单来说,通过 RPC 可以帮助我们调用远程计算机上某个服务的方法,这个过程就像调用本地方法一样简单。并且!我们不需要了解底层网络编程的具体细节。
举个例子:两个不同的服务 A、B 部署在两台不同的机器上,服务 A 如果想要调用服务 B 中的某个方法的话就可以通过 RPC 来做。一言蔽之:RPC 的出现就是为了让你调用远程方法像调用本地方法一样简单。
组件架构
- 客户端程序:发起远程调用请求。
- 客户端代理(Client Stub):负责序列化参数并通过网络发送请求。
- 传输层:网络传输协议,用于发送和接收数据。
- 服务器代理(Server Stub):负责反序列化请求并调用实际服务。
- 服务器程序:执行具体的操作并返回结果。
优点
简化分布式计算:开发人员不必关注网络通信的细节,可以像调用本地函数一样调用远程服务。
跨平台支持:使用IDL和代理生成,RPC可以支持不同操作系统和编程语言之间的互操作性。
模块化设计:RPC鼓励将应用程序分解为不同的服务模块,促进系统的模块化设计。
挑战
网络延迟和错误处理:由于RPC涉及网络通信,延迟和失败是不可避免的,开发人员需要处理这些情况。
安全性:远程调用涉及跨网络传输数据,可能存在安全风险,通常需要加密和认证机制。
版本兼容性:当客户端和服务器端的接口发生变化时,如何保持兼容性是一个挑战。
常见的RPC框架
1. gRPC
- 开发者:Google
- 协议:基于HTTP/2
- 数据格式:使用Protocol Buffers(Protobuf)作为接口定义语言和序列化格式。
- 特点:
- 支持多语言:gRPC支持包括C++, Java, Python, Go等多种编程语言。
- 高性能:由于使用了HTTP/2,gRPC支持多路复用、流式通信、头部压缩等特 性,提高了效率和速度。
- 双向流:gRPC支持双向流,客户端和服务器可以在同一个连接上同时发送和接收消息。
- 强大的生态系统:gRPC在微服务架构中被广泛采用,并且有丰富的生态工具支持,如gRPC Gateway可以方便地暴露REST API。
- 缺点:
- 通过 ProtoBuf 定义接口和数据类型还挺繁琐的
- 几乎没有服务治理能力,需要依赖其他组件,比如腾讯北极星
2. Apache Thrift
- 开发者:最初由Facebook开发,后来转移到Apache基金会
- 协议:支持多种传输协议和编码格式
- 数据格式:自定义二进制格式,可以使用IDL(Interface Definition Language)生成代码
- 特点:
- 跨语言支持:Thrift支持多种编程语言,包括Java、C++、Python、PHP、Ruby等,适合跨语言应用程序开发。
- 灵活性:Thrift提供了多种传输协议(如TCP、HTTP)和编码格式(如二进制、JSON)。
- 轻量级:相比一些其他RPC框架,Thrift较为轻量,适合低延迟应用。
3. Apache Dubbo
- 开发者:阿里巴巴,后捐赠给Apache基金会
- 协议:基于自定义的RPC协议
- 数据格式:支持多种序列化方式,包括Hessian、JSON、Protobuf等
- 特点:
- 微服务支持:Dubbo天生支持微服务架构,具有服务发现、负载均衡、熔断等功能。
- 高可用性:Dubbo内置了服务治理功能,如服务降级、失败重试等,增强了系统的健壮性。
- 扩展性:Dubbo提供了丰富的扩展点,可以根据需求自定义功能。
4. Hessian
- 开发者:Caucho Technology
- 协议:基于HTTP
- 数据格式:二进制序列化格式
- 特点:
- 简洁高效:Hessian使用二进制格式进行数据传输,性能较高,且易于实现。
- 跨语言支持:虽然Hessian最初是为Java设计的,但也有多种语言的实现版本。
- 轻量级:Hessian适合资源受限的环境,如嵌入式系统或移动设备。
5. RMI (Remote Method Invocation)
- 开发者:Sun Microsystems(现为Oracle)
- 协议:基于Java的自定义协议
- 数据格式:Java序列化
- 特点:
- 深度集成:RMI是Java平台的一部分,支持在不同Java虚拟机之间调用对象的方法。
- 强类型支持:由于是Java原生支持,RMI可以直接使用Java对象,类型安全且易于使用。
- 局限性:RMI仅适用于Java环境,不支持跨语言调用。
总结
RPC的核心原理在于将复杂的网络通信过程隐藏在调用机制之下,使开发者可以像调用本地函数一样调用远程函数。通过序列化、反序列化、网络传输、代理机制,RPC实现了跨网络的过程调用,从而支持分布式系统和服务的构建。
gRPC 和 Thrift 虽然支持跨语言的 RPC 调用,但是它们只提供了最基本的 RPC 框架功能,缺乏一系列配套的服务化组件和服务治理功能的支撑。
Dubbo 不论是从功能完善程度、生态系统还是社区活跃度来说都是最优秀的。而且,Dubbo 在国内有很多成功的案例比如当当网、滴滴等等,是一款经得起生产考验的成熟稳定的 RPC 框架。最重要的是你还能找到非常多的 Dubbo 参考资料,学习成本相对也较低。
参考:
有了 HTTP 协议,为什么还要有 RPC ?