什么是RPC

简介: 1.为什么需要RPC为什么需要 RPC 呢?通俗的讲就是无法在一个进程内,甚至一个计算机内通过本地调用的方式完成的需求,比如不同的系统间的通讯,甚至不同的组织间的通讯。由于计算能力需要横向扩展,需要在多台机器组成的集群上部署应用,

cea0246304d348d087b935f4d133a4d2.png

1.为什么需要RPC

为什么需要 RPC 呢?通俗的讲就是无法在一个进程内,甚至一个计算机内通过本地调用的方式完成的需求,

比如不同的系统间的通讯,甚至不同的组织间的通讯。

由于计算能力需要横向扩展,需要在多台机器组成的集群上部署应用,

2.RPC(远程过程调用)是什么

简单的说,RPC就是从一台机器(客户端)上通过参数传递的方式调用另一台机器(服务器)上的一个函数或方法(可以统称为服务)并得到返回的结果。

RPC 会隐藏底层的通讯细节(不需要直接处理Socket通讯或Http通讯)

RPC 是一个请求响应模型。客户端发起请求,服务器返回响应(类似于Http的工作方式)

RPC 在使用形式上像调用本地函数(或方法)一样去调用远程的函数(或方法)。

远程过程调用发展历程

2.1早期成熟的 RPC

ONC RPC (开放网络计算的远程过程调用),

OSF RPC(开放软件基金会的远程过程调用)

CORBA(Common Object Request Broker Architecture公共对象请求代理体系结构)

DCOM(分布式组件对象模型),COM+

NET Remoting

XML-RPC,SOAP,Web Service

PHPRPC,Hessian,JSON-RPC

Microsoft WCF,WebAPI

ZeroC Ice,Thrift,GRPC

Hprose

2.2 Java RMI

我们着重,聊一下Java RMI 通过创建存根函数来工作。存根由 rmic 编译器生成。自 Java 1.5 以来,Java 支持在运行时动态生成存根类。编译器 rmic 会提供各种编译选项。

RMI 架构

2f824bff48874a04b9d0f7748ef6d892.png

RMI 是一个三层架构。最上面是 Stub/Skeleton layer(存根/骨架层)。方法调用从 Stub、Remote Reference Layer (远程引用层)和 Transport Layer(传输层)向下,传递给主机,然后再次经传 Transport Layer 层,向上穿过 Remote Reference Layer 和 Skeleton ,到达服务器对象。 Stub 扮演着远程服务器对象的代理的角色,使该对象可被客户激活。Remote Reference Layer 处理语义、管理单一或多重对象的通信,决定调用是应发往一个服务器还是多个。Transport Layer 管理实际的连接,并且追踪可以接受方法调用的远程对象。服务器端的 Skeleton 完成对服务器对象实际的方法调用,并获取返回值。返回值向下经 Remote Reference Layer 、服务器端的 Transport Layer 传递回客户端,再向上经 Transport Layer 和 Remote Reference Layer 返回。最后,Stub 程序获得返回值。

4989761a276c4d56b4c6a50af124f7fa.png

BankAccount acct = new BankAcctImpl();
String url = "rmi://java.sun.com/account";
// bind url to remote object
java.rmi.Naming.bind(url, acct);
// look up account
acct = (BankAccount)java.rmi.Naming.lookup(url);

2.3早期的 RPC历史发展进程

第一代 RPC(ONC RPC,OSF RPC)不支持对象的传递。

CORBA 太复杂,各种不同实现不兼容,一般程序员也玩不转。

DCOM,COM+ 逃不出 Windows 的手掌心。

RMI 只能在 Java 里面玩。NET Remoting 只能在 .NET 平台上玩。XML-RPC,SOAP,WebService冗余数据太多,处理速度太慢。RPC 风格的 Web Service 跨语言性不佳,而 Document 风格的 Web Service 又太过难用。

Web Service 没有解决用户的真正问题,只是把一个问题变成了另一个问题。

Web Service 的规范太过复杂,以至于在 .NET 和 Java 平台以外没有真正好用的实现,甚至没有可用的实现。

跨语言跨平台只是 Web Service 的一个口号,虽然很多人迷信这一点,但事实上它并没有真正实现。

2.3.1 PHPRPC

基于 PHP 内置的序列化格式,在跨语言的类型映射上存在硬伤。

通讯上依赖于 HTTP 协议,没有其它底层通讯方式的选择。

内置的加密传输既是特点,也是缺点。

虽然比基于 XML 的 RPC 速度快,但还不是足够快。

2.3.2 Hessian

二进制的数据格式完全不具有可读性。

官方只提供了两个半语言的实现(Java,ActionScript 和不怎么完美的 Python 实现),其它语言的第三方实现良莠不齐。

支持的语言不够多,对 Web 前端的 JavaScript 完全无视。

虽然是动态 RPC,但动态性仍然欠佳。

虽然比基于 XML 的 RPC 速度快,但还不是足够快。

2.3.3 JSON-RPC

JSON 具有文本可读性,且比 XML 更简洁。

JSON 受 JavaScript 语言子集的限制,可表示的数据类型不够多。

JSON 格式无法表示数据内的自引用,互引用和循环引用。

某些语言具有多种版本的实现,但在类型影射上没有统一标准,存在兼容性问题。

JSON-RPC 虽然有规范,但是却没有统一的实现。在不同语言中的各自实现存在兼容性问题,无法真正互通。

2.3.4 Microsoft WCF,WebAPI

它们是微软对已有技术的一个 .NET 平台上的统一封装,是对 .NET Remoting、WebService 和基于 JSON 、XML 等数据格式的 REST 风格的服务等技术的一个整合。虽然号称可以在 .NET 平台以外来调用它的这些服务,但实际上跟在 .NET 平台内调用完全是两码事。它没有提供任何在其他平台的语言中可以使用的任何工具。

3. 如何选型RPC框架

我们需要考虑如下这些问题

3.1如何表示数据

在本地系统上不存在数据不相容的问题,因为数据格式总是相同的。而在分布式系统中,不同远程机器上可能有不同的字节顺序,不同大小的整数,以及不同的浮点表示。对于 RPC,如果想与异构系统通信,我们就需要想出一个“标准”来对所有数据类型进行编码,并可以作为参数传递。例如,ONC RPC 使用 XDR (eXternal Data Representation) 格式 。这些数据表示格式可以使用隐式或显式类型。隐式类型,是指只传递值,而不传递变量的名称或类型。常见的例子是 ONC RPC 的 XDR 和 DCE RPC 的 NDR。显式类型,指需要传递每个字段的类型以及值。常见的例子是 ISO 标准 ASN.1 (Abstract Syntax Notation)、JSON (JavaScript Object Notation)、Google Protocol Buffers、以及各种基于 XML 的数据表示格式。

3.2 如何选用传输协议

有些实现只允许使用一个协议(例如 TCP )。大多数 RPC 实现支持几个,并允许用户选择。

3.3 出错时,会发生什么

相比于本地过程调用,远程过程调用出错的机会将会更多。由于本地过程调用没有过程调用失败的概念,项目使用远程过程调用必须准备测试远程过程调用的失败或捕获异常。

3.4 远程调用的语义是什么

调用一个普通的过程语义很简单:当我们调用时,过程被执行。远程过程完全一次性调用成功是非常难以实现。执行远程过程可以有如下结果:

如果服务器崩溃或进程在运行服务器代码之前就死了,那么远程过程会被执行0次;

如果一切工作正常,远程过程会被执行1次;

如果服务器返回服务器存根后在发送响应前就奔溃了,远程过程会被执行1次或者多次。客户端接收不到返回的响应,可以决定再试一次,因此出现多次执行函数。如果没有再试一次,函数执行一次;

如果客户机超时和重新传输,那么远程过程会被执行多次。也有可能是原始请求延迟了。两者都可能会执行或不执行。

RPC 系统通常会提供至少一次或最多一次的语义,或者在两者之间选择。如果需要了解应用程序的性质和远程过程的功能是否安全,可以通过多次调用同一个函数来验证。如果一个函数可以运行任何次数而不影响结果,这是幂等(idempotent)函数的,如每天的时间、数学函数、读取静态数据等。否则,它是一个非幂等(nonidempotent)函数,如添加或修改一个文件)。

3.5 远程调用的性能怎么样

毫无疑问,一个远程过程调用将会比常规的本地过程调用慢得多,因为产生了额外的步骤以及网络传输本身存在延迟。然而,这并不应该阻止我们使用远程过程调用。

3.6 远程调用安全吗?

使用 RPC,我们必须关注各种安全问题:

客户端发送消息到远程过程,那个过程是可信的吗?

客户端发送消息到远程计算机,那个远程机器是可信的吗?

服务器如何验证接收的消息是来自合法的客户端吗?服务器如何识别客户端?

消息在网络中传播如何防止时被其他进程嗅探?

可以由其他进程消息被拦截和修改时遍历网络从客户端到服务器或服务器端?

协议能防止重播攻击吗?

如何防止消息在网络传播中被意外损坏或截断?

3.7 远程过程调用的优点

你不必担心传输地址问题。服务器可以绑定到任何可用的端口,然后用 RPC 名称服务来注册端口。客户端将通过该名称服务来找到对应的端口号所需要的程序。而这一切对于程序员来说是透明的。

系统可以独立于传输提供者。自动生成服务器存根使其可以在系统上的任何一个传输提供者上可用,包括 TCP 和 UDP,而这些,客户端可以动态选择的。当代码发送以后,接收消息是自动生成的,而不需要额外的编程代码。

应用程序在客户端只需要知道一个传输地址——名称服务,负责告诉应用程序去哪里连接服务器函数集。

使用函数调用模型来代替 socket 的发送/接收(读/写)接口。用户不需要处理参数的解析。

4. 其他常见RPC框架

Dubbo

Dubbo是阿里巴巴开源的高性能RPC框架,它支持多种协议和序列化方式,并提供了丰富的特性,例如负载均衡、集群容错、服务治理等。

gRPC

gRPC是Google开源的高性能RPC框架,它使用Protocol Buffers作为默认的序列化协议,支持多种语言和平台,并提供了基于HTTP/2协议的双向流式通信。

Thrift

Thrift是Facebook开源的跨语言RPC框架,它支持多种语言和平台,并提供了多种协议和序列化方式,包括二进制、压缩、JSON等。

Apache Axis

Apache Axis是Apache基金会的开源RPC框架,它提供了基于SOAP协议的Web服务和基于REST协议的Web服务。

Apache DubboX

Apache DubboX是Apache基金会的开源RPC框架,它是Dubbo框架的增强版,提供了更加灵活的扩展机制和更加丰富的特性。

JBoss Remoting

JBoss Remoting 是 JBoss 社区开发的一种 RPC 框架,它支持多种传输协议和数据格式,例如 TCP、UDP、HTTP、SOAP 等。

Apache Avro

Apache Avro 是 Apache 基金会的开源 RPC 框架,它使用二进制协议传输数据,并支持多种语言和平台。

目录
相关文章
|
人工智能 监控 数据可视化
BISHENG下一代企业AI应用的“全能型“LLM软件
杭州奥零数据科技有限公司成立于2023年,专注于数据中台业务,维护开源项目AllData并提供商业版解决方案。AllData提供数据集成、存储、开发、治理及BI展示等一站式服务,支持AI大模型应用,助力企业高效利用数据价值。
|
设计模式 算法 安全
【C/C++ 关键字 函数说明符 】C++ final关键字(修饰成员函数无法被子类重写覆盖)
【C/C++ 关键字 函数说明符 】C++ final关键字(修饰成员函数无法被子类重写覆盖)
1038 1
|
分布式计算 负载均衡 数据安全/隐私保护
什么是RPC?有哪些RPC框架?
RPC(Remote Procedure Call,远程过程调用)是一种允许运行在一台计算机上的程序调用另一台计算机上子程序的技术。这种技术屏蔽了底层的网络通信细节,使得程序间的远程通信如同本地调用一样简单。RPC机制使得开发者能够构建分布式计算系统,其中不同的组件可以分布在不同的计算机上,但它们之间可以像在同一台机器上一样相互调用。
999 8
|
缓存 运维 监控
CPU被打满/CPU 100%:高效应对策略与技术干货分享
【10月更文挑战第3天】在信息技术高速发展的今天,无论是开发人员、运维人员还是数据分析师,都可能遇到CPU被打满(即CPU使用率达到100%)的情况。这不仅会影响系统的响应速度,严重时甚至会导致服务中断。本文将从诊断、分析与解决三个方面,详细介绍处理CPU 100%问题的技术干货。
1416 3
|
Java 物联网 Python
物联网发展的三大编程语言
虽然Java是物联网开发中使用最多的语言,但是Java和Python在物联网开发的不同子域中紧随其后。物联网发展的未来可能仍然是多语言的。十年前,可能没有人想象未来有一天我们使用的空调、冰箱可以智能可控,路上行驶的汽车可以自动驾驶,现在,这些都将变得现实,而让这些变得现实的就是物联网。
22117 149
简单易操作 VsCoe离线安装插件【步骤+图片+插件】
这篇文章介绍了在Visual Studio Code (VSCode) 中进行离线安装插件的详细步骤,包括如何下载插件、以SVN插件为例的离线安装过程、通过命令行安装以及一个更加简单的离线安装方式,还提供了操作界面的截图帮助理解。
简单易操作 VsCoe离线安装插件【步骤+图片+插件】
|
数据库连接 Linux 数据库
GBase 8s数据库连接 – Python
GBase 8s数据库连接 – Python
|
Kubernetes 持续交付 容器
在K8S中,镜像的拉取策略有哪些?
在K8S中,镜像的拉取策略有哪些?
【ClickHouse】深入浅出系列之配置详解,全中文注释!
【ClickHouse】深入浅出系列之配置详解,全中文注释!

热门文章

最新文章