当前位置: 首页 > news >正文

操作系统:远程过程调用( Remote Procedure Call,RPC)

目录

什么是 RPC?

为什么需要 RPC?

RPC 中的消息

RPC 消息的结构

这些消息发送到哪里去?

RPC 是如何“伪装成”本地函数调用的?

Stub:伪装函数的“代理人”

什么是参数封装(Parameter Marshalling)?


我们现在来讲解一个在分布式系统中非常重要的通信机制:远程过程调用 Remote Procedure Call(RPC)

什么是 RPC?

Remote Procedure Call(RPC) 是一种协议,允许一个程序调用另一个远程计算机上的函数或服务,就好像它是本地函数一样,而无需了解网络通信的细节。

 RPC 的核心思想

虽然这个函数其实在另一台机器上,你仍然可以用和本地一样的方式去调用它。

RPC 做的事情可以简单地说是:不只是传数据,而是“远程执行一段代码”,并把结果带回来。

它的重点是:

  • 调用远程的“函数”或“服务”,而不仅仅是发一个数据包;

  • 你不需要关心它是不是在另一台机器上;

  • 系统帮你把调用过程变成“发送请求 → 执行函数 → 发送结果”的一套流程。

为什么需要 RPC?

一、先从我们熟悉的「打函数」说起

当你写程序的时候,比如调用一个加法函数:

result = add(3, 5)

你会发现:

  • 你只写了一句;

  • 函数在哪?在本地;

  • 参数怎么传?系统帮你传了;

  • 结果怎么回来?系统帮你拿回来了。

这就叫做本地函数调用:你只管调用,系统自动把一切“底层操作”都做好了。

二、再看看「进程之间怎么交流」(IPC)

有时候,两个程序(进程)需要互相传数据,比如:

  • 你运行的浏览器想从另一个本地程序拿图像;

  • 一个程序做运算,另一个来展示结果。

这就用到了进程间通信(IPC),比如:

  • A 进程用 send() 发一个消息;

  • B 进程用 receive() 接收消息;

  • 两个程序必须自己约定:这个消息是什么意思,内容要怎么解析。

 简单来说:

IPC 更像是“写信”交流,你发一个东西,我收一个东西。大家要约定好格式、理解内容,通信本身是“传数据”而不是“请求功能”。

三、现在来看看 RPC(远程过程调用)

好,现在问题来了:如果这个函数不在本地,而是在另一台电脑上怎么办?
比如你电脑上运行了一个程序,它想调用远程服务器上的函数。

你能不能像调用本地一样写一句:

result = remote_add(3, 5)

这时候,RPC 就派上用场了。

RPC 让你调用远程的函数,就像在本地调用一样。你不用自己写通信代码,不用关心网络传输细节。

IPC 是在“传数据”,RPC 是在“请求帮我做事”

RPC 把通信和函数调用结合起来,隐藏了底层复杂性,是写分布式程序非常常用的方式。

类比说明
IPC 像是写信你写信告诉对方一些内容(发送数据),对方自己想办法理解
RPC 像是打电话你直接打电话说“帮我做这件事”,对方立即照做,然后告诉你结果

RPC 与 IPC 的关系和区别

项目IPC(进程间通信)RPC(远程过程调用)
通信范围同一台主机的进程不同主机的进程
通信形式数据共享、消息传递等函数调用封装为消息
通信协议本地内核机制(管道、共享内存)网络协议(通常是 TCP/UDP)
消息内容可能是任意格式数据结构化:包含函数名和参数

 操作系统:进程间通信( Interprocess Communication,简称 IPC)-CSDN博客


RPC 中的消息

回顾一下:IPC 的消息是什么样的?

在传统的 IPC(进程间通信)中,消息就是一段“原始数据”,比如一个字符串、一个数字数组,或者某种格式的字节流。

"ADD 3 5"

这是程序 A 发给程序 B 的一句话,但程序 B 得自己想办法理解这句话的含义,比如:

  • 它是不是“加法”命令?

  • 后面两个数是什么意思?

  • 执行后结果要不要回给 A?

这完全靠开发者来设计和解释消息内容,而RPC 的消息是结构化的、有标准格式的。

RPC 消息的结构

RPC 系统为了让通信过程更像“调用函数”,而不是“发信息”,它设计了一套清晰的结构,让每条消息都包含下面这些内容:

  • 函数标识符(Function ID):客户端要调用哪个函数;

  • 参数数据(Arguments):传递给远程函数的参数;

  • 调用标识(Call ID):请求编号,用于匹配返回值;

  • 返回值(在响应中):函数执行的结果;

这使得 RPC 不再只是“传数据”,而是明确表达“请求执行一个功能,并返回结果”。

字段内容说明
函数名要执行的远程函数名称,例如 add()get_user()
参数值函数的参数,例如 3, 5user_id=42
唯一标识符每个请求有编号,方便匹配返回结果
返回通道信息哪个端口/地址返回结果

这意味着——RPC 的消息不再是“信封里写一堆字”,而是:

自动生成的、机器能看懂的函数调用说明书。

这些消息发送到哪里去?

每个运行 RPC 服务的远程主机上,通常有一个叫做 RPC daemon(守护进程) 的后台程序在监听某个端口(比如 1234 端口)。

当客户端发出 RPC 请求时,这条结构化消息会:

  1. 通过网络发给目标主机;

  2. 交给监听端口的 RPC 守护进程;

  3. 它读取消息,知道:

    • 要调用哪个函数

    • 参数是什么

  4. 然后在本地真正去执行这个函数;

  5. 把返回结果再次打包成消息,发送回客户端。

阶段内容
客户端发送请求消息中包含函数名、参数等
服务器端接收本地 RPC 服务进程(daemon)监听某个端口,解析消息
执行远程函数找到匹配的函数,执行传入的参数逻辑
返回结果服务器打包返回值,发送回客户端

 网络中的 RPC 通信流程图: 

Client                    Network                  Server
--------                 ---------                --------
Call fn(x, y)  ─────▶    封装消息包  ─────▶    RPC Daemon 解析⬇                             ⬇Send to IP:port           查找 fn 并执行(x, y)⬆                             ⬆接收返回值 ◀──── 回送结果消息 ◀──── 返回执行结果

 在 RPC 中,消息是自动构造的、有结构的,明确表示“调用哪个函数、传什么参数”,不像 IPC 那样只是发一段原始数据。

这让 RPC 能够像本地函数调用一样稳定、可控,并且适合在网络上传输和执行。


RPC 是如何“伪装成”本地函数调用的?

RPC(远程过程调用)希望让你写代码时像这样:

result = remote_add(3, 5)

看起来就像是调用一个本地函数 add(),但其实:

  • 函数 真正执行是在另一台机器上;

  • 数据是通过网络传过去的;

  • 然后结果又从远程传回来。

那它是怎么实现这么“骗你”的效果呢?这就靠存根(Stub)参数封装(Marshalling)。

Stub:伪装函数的“代理人”

Stub 是一个代理函数。你以为你调用的是远程函数,实际你调用的是一个“本地小助手”(Stub),它背后再去做真正的远程调用。

RPC 中有两个 Stub:

Stub 类型位置作用
Client Stub客户端模拟远程函数,接收参数、打包、发消息
Server Stub服务器端解包参数、调用真正的函数,打包返回结果

你以为你在调用远程服务器的 add(),其实你调用的是一个本地的“stub 函数”。

它不是真的运行 add(3, 5),而是做这几件事:

  1. 把函数名、参数等打包成一个消息;

  2. 通过网络发送给远程服务器;

  3. 等服务器执行完毕后,接收结果并返回给你。

这样你就“以为”是本地调用,实际上系统在偷偷做远程通信。

 调用流程图

【客户端】
你写的代码:result = remote_add(3, 5)│▼Client Stub(代理函数)└── 参数打包成消息│▼网络发送(消息)【服务器】Server Stub(接收者)└── 解包参数│▼真正执行:add(3, 5)│▼得到结果:8└── 结果打包成消息│▼网络返回(消息)【客户端】Client Stub 接收并解包│▼把 8 返回给调用者

什么是参数封装(Parameter Marshalling)?

参数封装是把多个参数“打包成可以在网络上传输的数据”。

比如:

remote_add(3, 5)

本地函数接收的是两个整数。

但网络不能直接发送“函数+数字”,它只能传输一串数据(比如文本、二进制)。

所以 stub 要把调用请求变成一个结构化的消息:

  1. 把 3 和 5 变成字节流;

  2. 加上函数名标识(比如 "add");

  3. 加上请求编号(为了匹配响应);

  4. 打包成一个结构清晰的消息。

这个过程就叫做 参数封装(Marshalling)。反过来,服务器也会用类似的方式把结果也打包发回去。 

响应过程也是一样

  • 远程服务器的 stub 接收到这个消息后解包;

  • 调用真正的函数 add(3, 5)

  • 拿到结果 8,再“封装”成返回消息;

  • 发送回客户端 stub;

  • 客户端 stub 解包,把结果还给你的代码。

RPC 的核心就是通过:

  • Stub:代理函数封装请求

  • 参数封装:打包参数成网络格式

  • 消息传输:靠 socket 等机制发送请求和响应

来实现“隐藏通信细节”的魔法。

http://www.dtcms.com/a/311491.html

相关文章:

  • MQTT 入门教程:三步从 Docker 部署到 Java 客户端实现
  • Linux基础学习笔记二
  • MySQL PostgreSQL JDBC URL 配置允许批量操作
  • C语言输入安全10大边界漏洞解析与防御
  • 基于LSTM模型与加权链路预测的动态热门商品成长性分析
  • SpringBoot相关注解
  • 项目管理平台是什么?概念、定义、作用、主流厂商解读
  • docker:将python开发的大模型应用,打成docker容器
  • C#中的除法
  • PostGIS面试题及详细答案120道之 (081-090 )
  • cuda编程笔记(12)--学习cuFFT的简单使用
  • 【Mybatis】MyBatis分页的三种实现方式,Log4j的使用
  • Elasticsearch 混合检索一句 `retriever.rrf`,把语义召回与关键词召回融合到极致
  • 模拟激光相机工作站版本6.0 5.2.32 6.0.44 6.031 5.2.20
  • 题解:P4447 [AHOI2018初中组] 分组
  • 归并排序(简单讲解)
  • [论文阅读] 人工智能 + 软件工程 | GitHub Marketplace中CI Actions的功能冗余与演化规律研究
  • 【RK3568 看门狗驱动开发详解】
  • Kubernetes Gateway API 详解:现代流量路由管理方案
  • 【最后203篇系列】030 强化学习探索
  • 浏览器及java读取ros1的topic
  • 重生之我在暑假学习微服务第八天《OpenFeign篇》
  • 暑期算法训练.13
  • cv弹窗,退款确认弹窗
  • 数据结构(12)二叉树
  • 深入 Go 底层原理(六):垃圾回收(GC)
  • 数据资产是什么?
  • MySQL 内置函数
  • npm安装下载慢问题
  • 离线安装docker和docker-compose