RPC(Remote Procedure Call)是一种允许程序像调用本地方法一样调用远程服务的通信协议,其核心价值在于屏蔽网络通信的底层复杂性,这与中间件“连接异构系统、简化开发”的核心目标完全一致。

参考文章:

什么是RPC?有哪些RPC框架?

一文搞定理解RPC

—RPC介绍一篇就够了&RPC的选择

推荐文章:从原理到选型,一文带你搞懂RPC

RPC

简介

RPC是远程过程调用(Remote Procedure Call)的缩写,是一种允许运行在一台计算机上的程序调用另一台计算机上子程序的技术。SAP系统RPC调用的原理其实很简单,有一些类似于三层构架的C/S系统,第三方的客户程序通过接口调用SAP内部的标准或自定义函数,获得函数返回的数据进行处理后显示或打印。远程过程调用(RPC)跨越了开放系统互连(OSI)网络通信模型中的传输层和应用层。

完整的RPC框架:服务发现、负载、容错、网络传输、序列化等组件

RPC协议

常说的RPC其实是RPC协议,即一种专门为服务间远程调用而设计的一种通用协议。该协议基于其它已有的传输协议,规定通信方式为C/S架构;并且在代码开发过程中要屏蔽掉底层通信细节,让开发者像调用本地方法一样,调用远程服务。RPC机制使得开发者能够构建分布式计算系统,其中不同的组件可以分布在不同的计算机上,但它们之间可以像在同一台机器上一样相互调用。

RPC组成

基于RPC协议内容的说明来看RPC的主要组成:

  • 确定一个已有的传输协议(TCP\UDP\HTTP\Websocket等)
  • 一个客户端通信实现模块(即客户端stub)
  • 一个服务端通信实现模块(即服务端stub)
  • 选择一个RPC内容协议(如:json、xml、protobuf等)

RPC主要有 5 个部分组成,分别是:客户端、客户端 Stub、网络传输模块、服务端 Stub、服务端等。
客户端(Client):服务调用方。
客户端存根(Client Stub):存放服务端地址信息,将客户端请求参数数据信息打包成网络消息,通过网络传输发送给服务端。
服务端存根(Server Stub):接收客户端发送过来的请求消息并进行解包,然后再调用本地服务进行处理。
服务端(Server):服务的真正提供者。
Network Service:底层传输,可以是 TCP 或 HTTP。

image-20250619112443294

现代化RPC框架的特点

  • 高性能:现代RPC框架通常采用高效的序列化协议和网络传输协议,以提高通信性能。
  • 跨语言支持:支持多种编程语言,使得不同语言编写的服务可以无缝通信。
  • 可扩展性:提供负载均衡、服务注册与发现等功能,以支持大规模分布式系统的部署和运维。
  • 安全性:支持加密传输和身份验证等安全机制,保障通信过程中的数据安全和隐私保护。

为什么需要RPC

微服务、分布式应用的开发越来越常见,RPC可以解决各个节点之间的服务调用以及通信问题

RPC框架会帮助我们做这些事情

  • 客户端stub、服务端stub的实现
  • 通信内容的序列化与反序列化实现(json、xml、protobuf)
  • 服务的注册与发现
  • 服务方负载均衡
  • 并发性能调优

有了RPC框架后,不需要再单独为项目开发这些基础功能了,这样开发具有RPC功能的客户端、服务端都跟开发普通本地模块一样方便。

RPC优点

  • 调用远程服务像调用本地方法一样方便
  • 多种传输协议可以选择
  • 为系统提供较强可扩展性、高可用性、维护性

治理功能,比如连接管理、健康检测、负载均衡、优雅启停机、异常重试、业务分组以及熔断限流等等

RPC协议的实现

dubbogrpcrestfulthrifthttp

rmihessianwebserivicememcachedredisrestjsonrpcmotanyar

这些协议可以适用于不同的业务场景,比如:dubbo协议适合高频的小数据量调用,hessian则适合文件传输,而jsonrpcgrpc则适合跨语言的应用。这些协议也与TCP等协议类似,都规定了自己的头信息body部分,用于约定通信的规则。

RPC实现思路

首先远程调用的大致链路其实都是大同小异的,大概可以分解出以下几个步骤:

  • 定义接口和数据类型:首先需要定义接口和数据类型,包括接口方法名、参数类型、返回值类型等。这些定义通常使用IDL(Interface Definition Language)语言来描述,以便于不同语言之间的调用和序列化。
  • 生成代码:根据接口和数据类型的定义,生成客户端和服务器端的代码。这些代码通常包括序列化和反序列化方法、网络传输方法等,以便于客户端和服务器端进行数据交换和通信。
  • 实现服务器端(被调用方):在服务器端实现接口方法,根据客户端请求进行相应的处理,并将处理结果返回给客户端。服务器端还需要实现服务注册和发现、负载均衡、容错等机制,以提高系统的可用性和可靠性。
  • 实现客户端(调用方):在客户端调用远程接口方法,将参数序列化并通过网络发送给服务器端,然后等待服务器端返回处理结果,并将结果反序列化后返回给调用方。客户端还需要实现服务发现和选择、负载均衡、重试等机制,以提高系统的可用性和可靠性。
  • 集成框架:将生成的代码和实现的服务器端、客户端集成到RPC框架中,并提供相应的API和工具,以便于开发人员使用和集成。
  • 测试和优化:对实现的RPC框架进行测试和优化,包括性能测试、功能测试、安全测试等,以确保系统的稳定性、可靠性和安全性。

RPC与HTTP的区别

RPC 和 HTTP 本质上是面向不同场景的产物。而RPC也可以基于HTTP协议来实现信息内容的传输。
RPC 和 HTTP 还有如下典型的区别:

  • RPC 可以基于 TCP、HTTP、WebStock 等作为基础传输协议,而 HTTP 只能是 http 协议
  • RPC 使用二进制来传输信息内容(体积更小),HTTP 则使用文本格式
  • RPC 的二进制序列化效率高,HTTP 的文本序列化(如json)则耗时多
  • RPC 基于 TCP 时可以网络 IO 多路复用,HTTP 不能很好的支持
  • RPC 可以很方便支持服务治理,而 HTTP 则需要单独实现支持

简而言之,就是RPC在远程调用的场景下,比 HTTP 更高效,更简洁、附加特性更强大,更适合分布式和微服务的场景。

RPC的应用

RPC在分布式系统中的系统环境建设和应用程序设计中有着广泛的应用,应用包括如下方面:

  1. 分布式操作系统的进程间通讯
    进程间通讯是操作系统必须提供的基本设施之一,分布式操作系统必须提供分布于异构的结点机上进程间的通讯机制,RPC是实现消息传送模式的分布式进程间通讯的手段之一。
  2. 构造分布式计算的软件环境
    由于分布式软件环境本身地理上的分布性,它的各个组成成份之间存在大量的交互和通讯,RPC 是其基本的实现方法之一。ONC+和DCE两个流行的分式布计算软件环境都是使用RPC构造的,其它一些分布式软件环境也采用了RPC方式。
  3. 远程数据库服务
    在分布式数据库系统中,数据库一般驻存在服务器上,客户机通过远程数据库服务功能访问数据库服务器,现有的远程数据库服务是使用RPC模式的。例如,SybaseOracle都提供了存储过程机制,系统与用户定义的存储过程存储在数据库服务器上,用户在客户端使用RPC模式调用存储过程
  4. 分布式应用程序设计
    RPC机制与RPC工具为分布式应用程序设计提供了手段和方便, 用户可以无需知道网络结构和协议细节而直接使用RPC工具设计分布式应用程序。
  5. 分布式程序的调试
    RPC可用于分布式程序的调试。使用反向RPC使服务器成为客户并向它的客户进程发出RPC,可以调试分布式程序。例如,在服务器上运行一个远端调试程序,它不断接收客户端的RPC,当遇到一个调试程序断点时,它向客户机发回一个RPC,通知断点已经到达,这也是RPC用于进程通讯的例子。

RPC 原理

RPC 调用流程

  1. 服务消费者(Client 客户端)通过本地调用的方式调用服务
  2. **客户端存根(Client Stub)接收到调用请求后负责将方法、入参等信息序列化(组装)**成能够进行网络传输的消息体。
  3. 客户端存根(Client Stub)找到远程的服务地址,并且将消息通过网络发送给服务端
  4. **服务端存根(Server Stub)收到消息后进行解码(反序列化)**。
  5. **服务端存根(Server Stub)**根据解码结果调用本地的服务进行相关处理
  6. 服务端(Server)本地服务业务处理。并将处理结果返回给服务端存根(Server Stub)。
  7. **服务端存根(Server Stub)**序列化结果。
  8. 服务端存根(Server Stub)将结果通过网络发送至消费方
  9. **客户端存根(Client Stub)接收到消息,并进行解码(反序列化)**。
  10. 服务消费者(Client 客户端)服务消费方得到最终结果

image-20250619112546216

RPC 框架提供了一系列的功能来支持上述过程,包括但不限于:

  • 接口定义:定义服务端和客户端之间的接口,确保双方能够正确理解和调用。
  • 数据序列化与反序列化:将调用信息和结果转换为网络可传输的格式,并在接收时进行还原。
  • 网络通信:封装底层的网络通信逻辑,使得开发者无需关心具体的网络细节。
  • 负载均衡:在多个服务实例之间分配请求,提高系统的可扩展性和可用性。
  • 服务注册与发现:在分布式系统中,自动发现可用的服务实例。

透明化远程服务调用 实现

对java来说就是使用代理!java代理有两种方式: jdk 动态代理字节码生成。尽管字节码生成方式实现的代理更为强大和高效,但代码维护不易,大部分公司实现RPC框架时还是选择动态代理方式。

通过动态代理模式,在执行该方法的前后对数据进行封装和解码等,让用于感觉就像是直接调用该方法一样,殊不知,我们对方法前后都经过了复杂的处理。

需要实现RPCProxyClient代理类,代理类的invoke方法中封装了与远端服务通信的细节,消费方首先从RPCProxyClient获得服务提供方的接口,当执行helloWorldService.sayHello(“test”)方法时就会调用invoke方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
public class RPCProxyClient implements java.lang.reflect.InvocationHandler{
private Object obj;
public RPCProxyClient(Object obj){
this.obj=obj;
}
// 得到被代理对象
public static Object getProxy(Object obj){
return java.lang.reflect.Proxy.newProxyInstance(obj.getClass().getClassLoader(),
obj.getClass().getInterfaces(), new RPCProxyClient(obj));
}
// 调用此方法执行
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
Object result = new Object(); // 结果参数
// ...执行通信相关逻辑
// ...
return result;
}
}

public class Test {
public static void main(String[] args) {
HelloWorldService helloWorldService = (HelloWorldService)RPCProxyClient.getProxy(HelloWorldService.class);
helloWorldService.sayHello("test");
}
}

RPC框架

封装好参数编组、消息解组、底层网络通信的RPC程序开发框架,带来的便捷是可以直接在其基础上只需要专注于过程代码编写。

目前常用的RPC框架

  1. Dubbo:Dubbo是一个分布式服务框架,以及SOA治理方案。

    其功能主要包括:高性能NIO通讯及多协议集成,服务动态寻址与路由,软负载均衡与容错,依赖分析与降级等。

    Dubbo是阿里巴巴内部的SOA服务化治理方案的核心框架,Dubbo自2011年开源后,已被许多非阿里系公司使用。

  2. Spring Cloud:Spring Cloud由众多子项目组成,如Spring Cloud Config、Spring Cloud Netflix、Spring Cloud Consul 等,提供了搭建分布式系统及微服务常用的工具,如配置管理、服务发现、断路器、智能路由、微代理、控制总线、一次性token、全局锁、选主、分布式会话和集群状态等,满足了构建微服务所需的所有解决方案。Spring Cloud基于Spring Boot, 使得开发部署极其简单。

  3. gRPC: 一开始由 google 开发,是一款语言中立、平台中立、开源的远程过程调用(RPC)系统。

  4. Thrift :是一种轻量级的跨语言 RPC 通信方案,支持多达 25 种编程语言,用来进行可扩展且跨语言的服务的开发。它结合了功能强大的软件堆栈和代码生成引擎,以构建在 C++, Java, Python, PHP, Ruby, Erlang, Perl, Haskell, C#, Cocoa, JavaScript, Node.js, Smalltalk, and OCaml 这些编程语言间无缝结合的、高效的服务。

常见RPC框架对比

gRPC Apache Dubbo Apache Thrift Motan
开发者 Google 阿里巴巴 Apache 新浪微博开源
协议 使用HTTP/2协议作为底层传输协议,HTTP/2支持多路复用、头部压缩和服务器推送等特性,可提高性能和效率
使用Protocol Buffers(ProtoBuf)作为序列化协议,protobuf是一种高效紧凑的二进制序列化协议,适合高性能通信
支持多种传输协议,包括dubbo、rmi、http、hessian、webservice、rest等。
支持多种序列化协议,如hessian、json、protobuf等
支持多种传输协议和序列化协议,如TBinaryProtocolTCompactProtocol ——
支持语言 支持多语言,包括C++、Java、Python、Go、Ruby、C#、Node.js等 主要基于Java,但可以通过扩展支持其他语言 支持多语言,包括C++、Java、Python、Go、Ruby、C#、Node.js等。 ——
特点 提供强大的IDL(接口定义语言)和自动代码生成工具。
支持双向流、流式传输等特性。
适用于大规模分布式系统,要求高性能和跨语言支持的场景。
适用于需要使用Protocol Buffers进行高效数据序列化的场景。
提供高性能、透明化的远程方法调用。
支持负载均衡、服务发现、集群容错等特性。
提供了REST风格的远程调用。
适用于Java生态系统中的分布式应用,尤其是基于Spring的应用。
适用于需要提供多协议支持和高度可扩展性的场景。
使用IDL进行接口定义,提供代码生成工具。
支持异步和同步的通信方式。
可以在不同语言之间进行跨语言通信。
适用于异构系统中不同语言之间的远程调用。
适用于需要高度定制和支持多种传输协议的场景。
是一个Java框架,具有高性能和可扩展性。
在微博平台中已经广泛应用,每天为数百个服务完成近千亿次的调用。
提供了丰富的功能和良好的性能表现。
优点 高性能、低延迟、跨语言支持、多种通信协议、流式传输支持。 丰富的服务治理功能、高度可扩展、支持大规模分布式系统、灵活的扩展机制。 跨语言支持、多种序列化方式、代码生成工具、高效的数据传输。 ——
适用场景 大规模分布式系统、跨语言通信、需要高性能和低延迟的实时通信场景。 Java应用程序的分布式服务、需要服务治理功能的场景。 跨语言通信、大数据分析、需要高效数据传输的场景。 ——

其他RPC框架

其他框架:如Tars(腾讯内部使用并开源)、ZeroMQ(高性能异步消息传递库,非专门RPC框架)、Akka(并发编程框架,提供Actor模型实现)等。
特点

  • 这些框架各有特色,如 Tars 特别支持 C++ 语言,适合高性能要求的应用场景。
  • ZeroMQ 适用于构建高度异步、消息驱动的系统。
  • Akka 适用于构建高并发、分布式、容错性强的系统。

RPC协议选择

平时搭建业务一般可以通过业务上所需要的通信特点进行去选择。例如:

  • 如果是im场景下 WebRTC去提高通讯效率
  • 如果是大型电商那种分布式系统的话可以使用gRPC,java则使用Dubbo
  • 如果是搭建数据中心考虑跨语言则去选择Apache Thrift,
  • 如果最简单平常的也可以直接利用Springcloud中的Spring Cloud Netflix项目实现的多种组件,如Ribbon、Feign、Hystrix等,用于构建分布式系统中的服务通信和治理。

序列化协议

对于如何标识数据的做法是将交互双方所涉及的数据转换为某种事先约定好的中立数据流格式来进行传输,将数据流转换回不同语言中对应的数据类型来进行使用,就是序列化协议的初衷。一个好的序列化协议作用如下:

  • 跨语言和跨平台: 分布式系统中,不同计算机可能使用不同编程语言和操作系统,因此需要一种通用的数据格式,以便跨语言和跨平台进行数据传输和交互。序列化协议将数据转换为一种通用的格式,使得不同计算机之间可以正确地对数据进行编码和解码。
  • 数据压缩: 在网络传输过程中,数据的大小会影响网络带宽和传输速度,因此需要对数据进行压缩。序列化协议可以*将数据压缩为更小的二进制格式,从而减少网络传输的数据量,提高网络传输效率。
  • 数据安全: 在网络传输过程中,数据可能会被篡改或窃取,因此需要对数据进行加密和解密。序列化协议可以将数据转换为二进制格式,并进行加密和解密操作,从而保证数据的安全性和完整性。
  • 数据可读性: 在调试和排错过程中,需要查看网络传输的数据内容,以便于定位问题。序列化协议可以将数据转换为文本格式,使得数据更易于读取和理解。

几个常见的 rpc 的地址

grpc中文文档:https://doc.oschina.net/grpc

grpc官方文档:https://grpc.io/docs/

dubbo官方文档:https://cn.dubbo.apache.org/zh-cn/overview/home/

Apache Thrift官方文档:https://thrift.apache.org/

WebRTC官方文档:https://webrtc.org/?hl=zh-cn