【分布式理论7】分布式调用之:服务间的(RPC)远程调用

news2025/2/11 9:20:25

文章目录

    • 一、RPC 调用过程
    • 二、RPC 动态代理:屏蔽远程通讯细节
      • 1. 动态代理示例
      • 2. 如何将动态代理应用于 RPC
    • 三、RPC序列化与协议编码
      • 1. RPC 序列化
      • 2. RPC 协议编码
        • 2.1. 协议编码的作用
        • 2.2. RPC 协议消息组成
    • 四、RPC 网络传输
      • 1. 网络传输流程
      • 2. 关键优化点

一、RPC 调用过程

RPC(Remote Procedure Call,远程过程调用)是一种让不同网络节点上的服务相互调用的技术。它的核心目标是屏蔽远程调用的复杂性,使远程服务的调用方式如同本地调用一样简单。在分布式系统中,RPC 通过封装底层网络通信细节,提高了服务调用的可用性和开发效率。

RPC 调用流程包括:

在这里插入图片描述

  1. 动态代理:客户端通过代理对象调用远程方法。
  2. 序列化:将请求数据转换为二进制格式,便于传输。
  3. 协议编码:增加数据包的协议标识和长度信息。
  4. 网络传输:通过网络传递数据包。
  5. 协议解码:服务端解析请求包。
  6. 反序列化:将二进制数据转换回原始对象。
  7. 执行方法:调用对应的远程方法并处理请求。
  8. 响应返回:按照相同的序列化、网络传输等流程将响应结果返回给调用方。

 

二、RPC 动态代理:屏蔽远程通讯细节

动态代理(Dynamic Proxy)是 Java 提供的一种机制,允许在运行时动态创建代理对象,拦截方法调用,并在调用前后执行额外的逻辑。

在 RPC 场景中,动态代理的主要作用是屏蔽底层的远程通信细节,让客户端可以像调用本地方法一样调用远程服务。

1. 动态代理示例

示例代码:

public interface ServerProvider {
    void sayHello(String str);
}

public class ServerProviderImpl implements ServerProvider {
    @Override
    public void sayHello(String str) {
        System.out.println("Hello " + str);
    }
}

import java.lang.reflect.*;


/**
- `DynamicProxy` 实现了 `InvocationHandler`,用于拦截方法调用并执行代理逻辑。
- `invoke` 方法中:
    1. `method.invoke(realObject, args);` 通过反射调用真实对象的方法。
*/
public class DynamicProxy implements InvocationHandler {
    private Object realObject;
    
    public DynamicProxy(Object object) {
        this.realObject = object;
    }
    
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        return method.invoke(realObject, args);
    }
}

public class Client {
    public static void main(String[] args) {
        ServerProvider realServer = new ServerProviderImpl();
        InvocationHandler handler = new DynamicProxy(realServer);
        ServerProvider proxyInstance = (ServerProvider) Proxy.newProxyInstance(
            handler.getClass().getClassLoader(),
            realServer.getClass().getInterfaces(),
            handler);
        proxyInstance.sayHello("world");
    }
}

通过动态代理,客户端不直接依赖于 ServerProviderImpl,而是通过接口和代理类进行调用,这样:

  • 解耦了客户端和服务端,不需要在客户端硬编码调用远程方法。
  • 方便在代理类中加入 RPC 逻辑,比如序列化、网络传输等。
  • 增强扩展性,可以在 invoke 方法中添加日志、权限校验、负载均衡等功能。

 

2. 如何将动态代理应用于 RPC

(1) 在代理类中加入远程调用逻辑
(2) 客户端使用代理调用远程服务

@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    // 1. 构造 RPC 请求
    RpcRequest request = new RpcRequest();
    request.setMethodName(method.getName());
    request.setParameters(args);

    // 2. 发送请求到远程服务
    RpcResponse response = RpcClient.sendRequest(request);

    // 3. 解析响应并返回结果
    return response.getResult();
}


ServerProvider serverProvider = (ServerProvider) Proxy.newProxyInstance(
    getClass().getClassLoader(),
    new Class[]{ServerProvider.class},
    new RpcDynamicProxy("http://remote-server")
);
serverProvider.sayHello("world");

如果想进一步实现 RPC 的完整流程,可以加入序列化、网络传输、反序列化等模块,搭建一个真正的 RPC 组件!

 

三、RPC序列化与协议编码

1. RPC 序列化

序列化是将对象转换成字节流的过程,而反序列化则是恢复对象的过程。常见的序列化方式包括:

  • JSON:易读易用,但额外空间开销较大。
  • Hessian:二进制格式,序列化后字节数小,性能优于 JSON。
  • Protobuf:高效、跨语言支持,适用于大规模分布式应用。
  • Thrift:Facebook 开源的高效序列化框架,结合了 RPC 服务框架。

 

2. RPC 协议编码

2.1. 协议编码的作用

有了序列化功能,就可以将客户端的请求对象转化成字节流在网络上传输了,这个字节流转换为二进制信息以后会写入本地的 Socket 中,然后通过网卡发送到服务端。从编程角度来看,每次请求只会发送一个请求包,但是从网络传输的角度来看,网络传输过程中会将二进制包拆分成很多个数据包,这一点也可以从 TCP 传输数据的原理看出。拆分后的多个二进制包会同时发往服务端,服务端接收到这些数据包以后,将它们合并到一起,再进行反序列化以及后面的操作。

实际上,协议编码要做的事情就是对同一次网络请求的数据包进行拆分,并且为拆分得到的每个数据包定义边界、长度等信息。

 

2.2. RPC 协议消息组成

RPC 协议消息由 消息头消息体 组成:

  • 消息头 包含协议标识、数据长度、请求类型等信息。
  • 消息体 是序列化后的数据。

协议编码的核心目标是确保数据包正确地分片、合并,并提供必要的描述信息,保障网络传输的可靠性。

消息头部分主要存放消息本身的描述信息,如图所示。
在这里插入图片描述

名称描述
魔术位(magic)协议魔术,为解码设计
消息头长度(header size)用来描述消息头长度,为扩展设计
协议版本(version)协议版本,用于版本兼容
消息体序列化类型(st)描述消息体的序列化类型,例如 JSON、gRPC
心跳标记(hb)每次传输都会建立一个长连接,隔一段时间向接收方发送一次心跳请求,保证对方始终在线
单向消息标记(ow)标记是否为单向消息
响应消息标记(rp)用来标记是请求消息还是响应消息
响应消息状态码(status code)标记响应消息状态码
保留字段(reserved)用于填充消息,保证消息的字节是对齐的
消息 Id(message id)用来唯一确定一个消息的标识
消息体长度(body size)描述消息体的长度

 

四、RPC 网络传输

1. 网络传输流程

在 RPC 调用中,服务调用方(Client)需要发送请求给服务提供方(Server),然后等待服务器处理并返回响应数据。在这个过程中,数据在应用程序、操作系统内核、网络传输三个层次之间流动,并涉及多个数据复制操作。

从示意图中可以看出,数据的流转主要分为两部分:请求发送过程响应接收过程

在这里插入图片描述

请求发送流程(Client -> Server),服务调用方(Client)发起 RPC 请求,其数据流动过程如下:

步骤操作数据位置
1应用程序写入数据业务代码执行RPC调用,将数据写入应用缓冲区(User Space)
2数据复制到内核缓冲区操作系统将应用缓冲区的数据复制到内核缓冲区(Kernel Space)
3通过网络发送数据从内核缓冲区被传输到网卡(Network Card),并通过网络协议(如TCP)拆分成数据包发送到远程服务器
4服务器接收数据服务器端网卡接收数据包,并将其存入内核缓冲区
5数据复制到应用缓冲区服务器的内核将数据复制到应用缓冲区
6应用程序读取数据服务器端应用程序从应用缓冲区中获取数据,执行请求逻辑(如数据库查询、业务处理)

响应接收流程(Server -> Client):服务提供方(Server)处理完请求后,将结果返回给客户端,数据流动过程如下:

步骤操作具体内容
7应用程序写入数据服务器应用程序生成响应数据,并写入应用缓冲区
8数据复制到内核缓冲区服务器操作系统将数据从应用缓冲区复制到内核缓冲区,准备发送
9通过网络发送服务器的网卡将数据包发送到客户端
10客户端接收数据客户端网卡接收数据包,操作系统将其存入内核缓冲区
11数据复制到应用缓冲区数据从内核缓冲区复制到应用缓冲区,以便应用程序使用
12应用程序读取数据客户端应用程序从应用缓冲区中获取响应数据,完成 RPC 调用

通过上面对 RPC 调用流程的描述,可以看出服务调用方需要经过一系列的数据复制,才能通过网络传输将信息发送到服务提供方。此外可以看出网络 IO 传输和数据计算过程存在先后顺序,因此当前者出现延迟时会导致后者处于阻塞。另外,应用程序中存在同步调用和异步调用,因此衍生出了同步阻塞 IO(blocking IO)​、同步非阻塞 IO(non-blocking IO)​、多路复用 IO(multiplexing IO)这几种 IO 模式。(下篇分析ing)

 

2. 关键优化点

RPC 网络传输过程涉及多个阶段,包括数据在应用缓冲区、内核缓冲区、网络传输中的流转。优化 RPC 传输的关键在于减少数据复制、优化网络通信、使用异步 I/O 机制,提高整体性能。

操作具体内容
减少数据复制采用 零拷贝(Zero-Copy) 技术,如 mmapsendfile,避免数据在用户态和内核态之间频繁复制
优化网络传输使用 长连接(Keep-Alive) 避免频繁建立 TCP 连接;采用 批量发送数据压缩 来减少数据传输的开销
异步 I/O 处理使用 异步 I/O(如 Netty、epoll),避免同步阻塞,提高并发处理能力
优化缓冲区管理采用 池化缓冲区(Buffer Pool) 避免频繁申请和释放内存

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2295675.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Maven】项目管理工具-Maven

目录 1. Maven简介 1.1 项目管理 1.2 项目构建 1.3 项目构建工具 1.4 Maven的四大特征 1.4.1 依赖管理系统 1.4.2 多模块构建 1.4.3 一致的项目结构 1.4.4 一致的构建模型和插件机制 1.5 Maven模型 ​编辑 2.maven的安装配置 2.1 Maven的安装配置 2.1.1检测jdk的版…

ASP.NET Core WebSocket、SignalR

目录 WebSocket SignalR SignalR的基本使用 WebSocket WebSocket基于TCP协议,支持二进制通信,双工通信。性能和并发能力更强。WebSocket独立于HTTP协议,不过我们一般仍然把WebSocket服务器端部署到Web服务器上,因为可以借助HT…

【学术投稿】第五届计算机网络安全与软件工程(CNSSE 2025)

重要信息 官网:www.cnsse.org 时间:2025年2月21-23日 地点:中国-青岛 简介 第五届计算机网络安全与软件工程(CNSSE 2025)将于2025年2月21-23日在中国-青岛举行。CNSSE 2025专注于计算机网络安全、软件工程、信号处…

26~31.ppt

目录 26.北京主要的景点 题目 解析 27.创新产品展示及说明会 题目​ 解析 28.《小企业会计准则》 题目​ 解析 29.学习型社会的学习理念 题目​ 解析 30.小王-产品展示信息 题目​ 解析 31.小王-办公理念-信息工作者的每一天 题目​ 解析 26.北京主要的景点…

网络工程师 (28)IEEE802标准

前言 IEEE 802标准是由电气和电子工程师协会(IEEE)制定的一组局域网(LAN)和城域网(MAN)标准,定义了网络中的物理层和数据链路层。 一、起源与背景 IEEE 802又称为LMSC(LAN/MAN Stand…

背包问题1

核心: // f[i][j] 表示只看前i个物品,总体积是j的情况下,总价值是多少 //res maxx(f[n][]0-v] //f[i][j]: //1 不选第i个物品 f[i][j] f[i-1][j] //2 选第i个物品 f[i][j] f[i-1][j-v[i]] w[i]

Spring 中的设计模式详解

控制反转(IoC)和依赖注入(DI) IoC(Inversion of Control,控制反转) 是 Spring 中一个非常非常重要的概念,它不是什么技术,而是一种解耦的设计思想。IoC 的主要目的是借助于“第三方”(Spring 中的 IoC 容器) 实现具有依赖关系的对象之间的解耦(IOC 容器…

人类的算计与机器的算计

近日,国外一视频网站博主通过设定,使DeepSeek和ChatGPT开展了一场国际象棋对弈。前十分钟双方在正常对弈,互有输赢,且ChatGPT逐渐占优。随后DeepSeek突然以对话方式告诉ChatGPT,国际象棋官方刚刚更新了比赛规则&#x…

7 使用 Pydantic 验证 FastAPI 的请求数据

FastAPI 是一个快速、现代的 Web 框架,它提供了自动生成 OpenAPI 文档的功能,支持 Pydantic 模型进行请求和响应数据的验证。Pydantic 提供了强大的数据验证功能,可以帮助你确保请求的有效性,自动进行数据转换,并生成详…

U3D支持webgpu阅读

https://docs.unity3d.com/6000.1/Documentation/Manual/WebGPU-features.html 这里看到已经该有的差不多都有了 WOW VFX更是好东西 https://unity.com/cn/features/visual-effect-graph 这玩意儿化简了纯手搓一个特效的流程 如果按原理说就是compute shader刷position&#…

Mac安装配置使用nginx的一系列问题

brew安装nginx https://juejin.cn/post/6986190222241464350 使用brew安装nginx,如下命令所示: brew install nginx 如下图所示: 2.查看nginx的配置信息,如下命令: brew info nginxFrom:xxx 这样的,是n…

在CT107D单片机综合训练平台上,8个数码管分别单独依次显示0~9的值,然后所有数码管一起同时显示0~F的值,如此往复。

题目:在CT107D单片机综合训练平台上,8个数码管分别单独依次显示0~9的值,然后所有数码管一起同时显示0~F的值,如此往复。 延时函数分析LED首先实现8个数码管单独依次显示0~9的数字所有数码管一起同时显示0~F的值,如此往…

组件库选择:ElementUI 还是 Ant Design

🤍 前端开发工程师、技术日更博主、已过CET6 🍨 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 🕠 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 🍚 蓝桥云课签约作者、上架课程《Vue.js 和 E…

从运输到植保:DeepSeek大模型探索无人机智能作业技术详解

DeepSeek,作为一家专注于深度学习与人工智能技术研究的企业,近年来在AI领域取得了显著成果,尤其在无人机智能作业技术方面展现了其大模型的强大能力。以下是从运输到植保领域,DeepSeek大模型探索无人机智能作业技术的详解&#xf…

超越LSTM!TCN模型如何精准预测股市波动(附代码)

作者:老余捞鱼 原创不易,转载请标明出处及原作者。 写在前面的话:最近我用TCN时间卷积网络预测了标普500指数(SPX)的每日回报率,发现效果远超传统方法。TCN通过因果卷积和膨胀卷积捕捉时间序列的长期依赖关…

[每周一更]-(第133期):Go中MapReduce架构思想的使用场景

文章目录 **MapReduce 工作流程**Go 中使用 MapReduce 的实现方式:**Go MapReduce 的特点****哪些场景适合使用 MapReduce?**使用场景1. 数据聚合2. 数据过滤3. 数据排序4. 数据转换5. 数据去重6. 数据分组7. 数据统计8.**统计文本中单词出现次数****代码…

QML初识

目录 一、关于QML 二、布局定位和锚点 1.布局定位 2.锚点详解 三、数据绑定 1.基本概念 2.绑定方法 3.数据模型绑定 四、附加属性及信号 1.附加属性 2.信号 一、关于QML QML是Qt框架中的一种声明式编程语言,用于描述用户界面的外观和行为;Qu…

查询已经运行的 Docker 容器启动命令

一、导语 使用 get_command_4_run_container 查询 docker 容器的启动命令 获取镜像 docker pull cucker/get_command_4_run_container 查看容器命令 docker run --rm -v /var/run/docker.sock:/var/run/docker.sock cucker/get_command_4_run_container 容器id或容器名 …

协议_CAN协议

物理层特征 信号传输原理: CAN控制器根据CAN_L和CAN_H上的电位差来判断总线电平,总线电平分为显性电平(CAN_H与CAN_L压差 2v)、隐性电平(CAN_H与CAN_L压差 0v),发送方通过总线电平的变化&am…

QT修仙之路2-2 对话框 尚欠火候

警告对话框 相关代码 错误对话框 相关代码 消息对话框 相关代码 询问对话框 相关代码 相关代码 警告对话框 QMessageBox::warning(this,"错误","账号密码不能为空",QMessageBox::Ok);错误对话框 QMessageBox msgBox(QMessageBox::Critical,"错误…