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

Java-63 深入浅出 分布式服务 网络通信 RPC 与 RMI 详解

点一下关注吧!!!非常感谢!!持续更新!!!

🚀 AI篇持续更新中!(长期更新)

AI炼丹日志-29 - 字节跳动 DeerFlow 深度研究框斜体样式架 私有部署 测试上手 架构研究,持续打造实用AI工具指南!📐🤖

💻 Java篇正式开启!(300篇)

目前2025年07月02日更新到:
Java-61 深入浅出 分布式服务 一致性算法 Raft 多图详解
MyBatis 已完结,Spring 已完结,Nginx已完结,Tomcat已完结,分布式服务正在更新!深入浅出助你打牢基础!

📊 大数据板块已完成多项干货更新(300篇):

包括 Hadoop、Hive、Kafka、Flink、ClickHouse、Elasticsearch 等二十余项核心组件,覆盖离线+实时数仓全栈!
大数据-278 Spark MLib - 基础介绍 机器学习算法 梯度提升树 GBDT案例 详解

请添加图片描述

分布式架构网络通信

在分布式系统设计中,网络通信是最基础也是最重要的组成部分。在Java生态系统中,有多种技术可以实现远程服务通信,每种技术都有其特定的应用场景和实现原理:

  1. RMI (Remote Method Invocation):Java原生的远程调用框架
  2. Hessian:基于HTTP的轻量级RPC框架
  3. SOAP:基于XML的Web服务协议
  4. ESB (Enterprise Service Bus):企业服务总线
  5. JMS (Java Message Service):面向消息的中间件API

这些技术虽然实现方式不同,但都建立在相同的底层网络通信原理之上。

基本原理

网络通信基础

从计算机系统底层来看,网络通信的本质是将数据从一台计算机传输到另一台计算机。这个过程主要涉及两个关键组件:

  1. 传输协议

    • TCP:面向连接的可靠传输协议,提供数据顺序保证和重传机制
      • 三次握手建立连接
      • 滑动窗口控制流量
      • 四次挥手断开连接
    • UDP:无连接的不可靠传输协议,提供较低的延迟
      • 适用于实时性要求高但允许少量丢包的场景
      • 常用于视频会议、在线游戏等
  2. 网络IO模型

    • BIO (Blocking IO)
      • 同步阻塞模型
      • 每个连接需要一个独立线程处理
      • 适用于连接数较少的场景
    • NIO (Non-blocking IO)
      • 同步非阻塞模型
      • 基于Selector实现多路复用
      • 适合高并发场景
    • AIO (Asynchronous IO)
      • 异步非阻塞模型
      • 基于回调机制
      • 性能最高但实现复杂

高级抽象

在实际应用中,开发者很少直接操作底层协议,而是使用更高层次的抽象:

  • HTTP/HTTPS协议
  • WebSocket协议
  • 各种RPC框架

这些高级协议和框架封装了底层细节,提供了更友好的开发接口。

什么是RPC

RPC (Remote Procedure Call) 是一种分布式系统间的通信范式,其核心目标是让远程服务调用像本地调用一样简单。

RPC工作原理示例

假设有以下场景:

  1. 服务器A运行订单服务
  2. 服务器B运行支付服务
  3. 订单服务需要调用支付服务的支付接口

传统方式需要:

  • 建立网络连接
  • 序列化请求参数
  • 发送请求
  • 接收响应
  • 反序列化结果

而使用RPC框架后,开发者只需:

PaymentService payment = RPCClient.getProxy(PaymentService.class);
PaymentResult result = payment.pay(orderId, amount);

RPC核心特征

  1. 透明性:调用远程方法像调用本地方法一样
  2. 跨语言:许多RPC框架支持多语言互操作
  3. 高性能:通过协议优化减少通信开销
  4. 可扩展:支持服务注册与发现等分布式特性

RPC架构

在这里插入图片描述

一个完整的RPC架构包含以下组件及其详细工作流程:

1. Client (客户端)

  • 服务消费者
  • 发起远程调用
  • 典型行为:
    • 获取服务代理
    • 构造调用请求
    • 等待响应返回

2. Client Stub (客户端存根)

  • 代理对象
  • 核心职责:
    • 服务发现:从注册中心获取服务地址
    • 协议编码:将方法调用转换为网络消息
      • 方法名序列化
      • 参数序列化(JSON, Protobuf等)
    • 网络传输:通过通信框架发送请求
    • 结果解码:将响应数据反序列化为对象

3. Server (服务端)

  • 服务提供者
  • 包含实际业务实现
  • 典型行为:
    • 注册服务到注册中心
    • 监听处理请求
    • 执行本地方法

4. Server Stub (服务端存根)

  • 请求处理器
  • 核心职责:
    • 网络监听:接收客户端请求
    • 协议解码:解析请求数据
      • 识别目标方法
      • 反序列化参数
    • 方法调用:反射调用本地实现
    • 结果编码:序列化返回结果

Stub的工作流程示例

Client -> ClientStub: 调用远程方法
ClientStub -> Network: 序列化请求
Network -> ServerStub: 传输请求数据
ServerStub -> Server: 调用本地方法
Server -> ServerStub: 返回结果
ServerStub -> Network: 序列化响应
Network -> ClientStub: 传输响应数据
ClientStub -> Client: 返回调用结果

常见优化技术

  1. 连接池:复用TCP连接减少握手开销
  2. 异步调用:Future/Promise模式
  3. 负载均衡:多服务提供者情况下的流量分配
  4. 容错处理:超时重试、熔断降级等机制

RPC调用过程

在这里插入图片描述
● 客户端(Client)发起服务调用

  • 客户端通过本地接口调用的方式发起远程服务请求
  • 调用方式与调用本地方法类似,对开发者透明
  • 示例:Java中的RMI调用或Dubbo服务调用

● 客户端存根(Client Stub)处理请求

  • 接收客户端调用请求后,解析方法签名和参数
  • 将调用信息序列化为二进制数据:
    • 使用协议如Protocol Buffers、JSON或Java原生序列化
    • 包含方法名、参数类型、参数值等信息
  • 构建网络传输的消息包:
    • 添加消息头(如消息长度、版本号)
    • 封装序列化后的数据为传输格式

● 网络传输过程

  • 客户端通过Socket建立与服务端的TCP连接
  • 使用NIO或BIO模式发送消息数据包
  • 可能经过负载均衡器或服务注册中心路由
  • 典型应用场景:跨机房调用或微服务间通信

● 服务端存根(Server Stub)处理

  • 接收网络字节流并进行完整性校验
  • 反序列化过程:
    • 读取消息头解析协议版本
    • 根据协议定义解码方法调用信息
    • 重建方法参数对象
  • 完整性检查:校验方法签名和参数合法性

● 服务调用执行

  • 服务端存根通过反射机制定位本地服务实现
  • 参数类型转换和适配(如DTO转换)
  • 调用实际业务逻辑处理
  • 记录调用日志和监控指标

● 结果返回处理

  • 服务端将执行结果序列化:
    • 处理正常返回值或异常信息
    • 考虑压缩优化网络传输
  • 构建响应消息包:
    • 包含响应状态码
    • 附加调用耗时等元数据

● 客户端结果处理

  • 接收网络响应并校验完整性
  • 反序列化响应数据:
    • 解析响应状态
    • 重建返回结果对象
  • 异常处理机制:
    • 网络超时重试
    • 服务降级策略
  • 最终将结果返回给调用方

整个过程可能涉及:

  • 服务治理功能(熔断、限流)
  • 加密传输(TLS/SSL)
  • 异步回调机制
  • 跨语言支持(通过通用协议)
  • 性能优化(连接池、批处理)

PRC的主要目标是把 除第一步和最后一步的结果组转起来。
注意:无论是何种类型的数据,最终都需要转换为二进制流在网络上进行传输,数据的发送方需要将对象转换为二进制流,而数据的接收方则需要把二进制流在恢复为对象

在Java的RPC框架比较多,常见的:
● Hessian
● gRPC
● Thrift
● HSF(High Speed Service Framework)
● Dubbo
● 等等

RMI (Remote Method Invocation)

基本介绍

Java RMI(Remote Method Invocation,远程方法调用)是 Java 原生支持的分布式远程调用框架,它采用 JRMP(Java Remote Messaging Protocol)作为通信协议,是纯 Java 版本的分布式远程调用解决方案。RMI 主要用于不同 Java 虚拟机(JVM)之间的通信,这些 JVM 可以运行在不同的主机上,也可以运行在同一台主机上。通过 RMI,一个 JVM 中的对象可以调用另一个 JVM 中对象的方法,就像调用本地对象的方法一样简单。

工作原理

客户端组件

  1. 存根(Stub)

    • 远程对象在客户端的代理,负责隐藏网络通信细节
    • 实现了与远程对象相同的接口
    • 当客户端调用方法时,Stub 会将调用请求序列化并通过网络发送到服务器端
  2. 远程引用层(Remote Reference Layer)

    • 解析并执行远程引用协议
    • 处理远程对象的引用语义(如单一引用或复制引用)
    • 管理远程对象的生命周期
  3. 传输层(Transport)

    • 负责建立和管理网络连接
    • 发送方法调用请求
    • 传递远程方法参数(通过对象序列化)
    • 接收并返回远程方法执行结果
    • 使用 TCP/IP 协议进行通信

服务器端组件

  1. 骨架(Skeleton)

    • 接收客户端通过 Stub 发送的请求
    • 反序列化方法参数
    • 调用服务器端的实际对象方法
    • 将执行结果序列化并返回给客户端
    • 在新版 RMI 中,Skeleton 已被动态代理机制取代
  2. 远程引用层(Remote Reference Layer)

    • 处理远程引用语义
    • 将请求转发给适当的 Skeleton 或目标对象
    • 管理远程对象的注册和查找
  3. 传输层(Transport)

    • 监听客户端的入站连接(默认端口 1099)
    • 接收客户端请求
    • 将请求转发给远程引用层
    • 管理连接池和线程池

典型应用场景

  1. 分布式计算:将计算任务分配到多台机器上执行
  2. 远程服务调用:如访问远程数据库服务或文件服务
  3. 企业级应用集成:集成不同系统之间的功能
  4. 集群管理:管理分布在多台服务器上的服务实例

工作流程示例

  1. 服务器端创建远程对象实现
  2. 使用 RMI 注册表(rmiregistry)注册远程对象
  3. 客户端从注册表获取远程对象引用(通过名称查找)
  4. 客户端调用远程对象方法
  5. Stub 序列化参数并发送请求
  6. 服务器端 Skeleton 接收请求并调用实际方法
  7. 方法执行结果返回给客户端
  8. 客户端获取返回值继续执行

优缺点

优点

  • 简单易用,与本地方法调用语法相似
  • 完全 Java 实现,跨平台性好
  • 支持对象序列化和动态类加载
  • 内置安全机制

缺点

  • 仅支持 Java 语言间的通信
  • 性能不如一些二进制协议高效
  • 防火墙穿透能力较差
  • 在复杂网络环境下可能遇到连接问题

注册表:

以URL形式注册远程对象,并向客户端回复远程对象的引用。
在这里插入图片描述

远程调用(RPC)的详细执行过程

远程调用的完整流程

  1. 服务发现阶段

    • 客户端首先通过远程服务器的注册中心(如Zookeeper、Nacos等)查询服务注册信息
    • 注册中心返回可用的服务实例列表和元数据信息
    • 客户端根据负载均衡策略选择一个合适的服务实例
  2. 代理调用阶段

    • 客户端持有的桩对象(Stub)实现了与远程服务完全一致的接口
    • 当客户端调用桩对象的方法时(如userService.getUser(id)),桩对象会:
      • 序列化方法名和参数(使用JSON、Protobuf等格式)
      • 生成唯一的请求ID用于跟踪调用
      • 添加必要的元数据(如超时设置、认证信息)
  3. 网络传输阶段

    • 远程引用层将本地调用转换为网络请求:
      • 确定目标服务器的地址和端口
      • 建立TCP连接(或复用连接池中的连接)
      • 将序列化后的请求数据通过传输层发送
    • 典型实现方式:
      • HTTP协议(如RESTful API)
      • 二进制协议(如gRPC的HTTP/2)
      • 自定义协议(如Dubbo的TCP协议)
  4. 服务器处理阶段

    • 传输层监听端口(如8080),接收到请求后:
      • 解析协议头信息
      • 验证请求合法性(如认证、限流)
      • 将请求转发给上层的远程引用层
    • 远程引用层执行:
      • 将网络请求转换为本地对象引用
      • 反序列化方法名和参数
      • 查找对应的服务实例和方法
  5. 实际调用阶段

    • 骨架(Skeleton)组件:
      • 验证参数类型和数量
      • 准备调用上下文(如事务、跟踪ID)
      • 通过反射机制调用实际的服务实现
    • 服务实现类执行真正的业务逻辑:
      • 访问数据库
      • 调用其他服务
      • 执行计算任务

结果返回的详细过程

  1. 服务器端结果处理

    • 业务方法执行完成后:
      • 返回值被骨架组件捕获
      • 异常情况会被转换为特定的错误码
    • 序列化过程:
      • 使用与请求相同的序列化协议
      • 可能包含附加信息(如执行耗时、扩展字段)
  2. 网络传输返回

    • 传输层将响应数据分包发送:
      • 大响应可能被拆分为多个TCP包
      • 需要处理网络抖动和重传
    • 常见的优化措施:
      • 数据压缩(如Gzip)
      • 批量响应(如多个请求合并返回)
  3. 客户端结果处理

    • 客户端传输层:
      • 接收数据包并重组完整响应
      • 处理网络超时和重试逻辑
    • 桩对象反序列化:
      • 将二进制数据转换为Java对象
      • 处理异常和错误码
      • 验证响应完整性(如校验和)
  4. 最终结果交付

    • 桩对象将反序列化的结果返回给调用方:
      • 同步调用:直接返回结果对象
      • 异步调用:返回Future或回调处理
    • 资源清理:
      • 关闭网络连接
      • 释放缓冲资源
      • 记录调用指标(用于监控)

典型应用场景示例

  1. 微服务架构中的服务调用

    • 订单服务调用库存服务的扣减接口
    • 用户服务查询权限服务的角色信息
  2. 分布式计算任务

    • MapReduce任务分发
    • 分布式机器学习参数同步
  3. 跨语言系统集成

    • Java服务调用Python的算法服务
    • Go语言编写的支付服务被NodeJS电商系统调用
  4. 云原生应用

    • Kubernetes Pod之间的服务发现和调用
    • Serverless函数间的相互调用
http://www.lryc.cn/news/579323.html

相关文章:

  • Spring 为何需要三级缓存解决循环依赖,而不是二级缓存
  • 【网络安全】Webshell命令执行失败解决思路
  • 【第十一篇】SpringBoot缓存技术
  • Javaweb - 10.1 Servlet
  • C盘空间的“元凶”——虚拟内存的神秘面纱
  • css ::before学习笔记
  • 专业AI工具导航与人工智能学习平台AIbase.cn 连接现在与AI未来的智能桥梁
  • YOLO基础算法入门之YOLOv8中的C2f(C2-Faster)高效特征提取结构
  • STC8G 8051内核单片机开发 (中断)
  • 算法学习笔记:4.KMP 算法——从原理到实战,涵盖 LeetCode 与考研 408 例题
  • 家政维修小程序源码php方案解析
  • FASTAPI+VUE3平价商贸管理系统
  • 实际开发如何快速定位和解决死锁?
  • thinkphp中间件
  • 协同过滤推荐算法
  • 动态规划-P1216 [IOI 1994] 数字三角形 Number Triangles
  • RAG实战指南 Day 4:LlamaIndex框架实战指南
  • AutoMedPrompt的技术,自动优化提示词
  • 基于 govaluate 的监控系统中,如何设计灵活可扩展的自定义表达式函数体系
  • 【学习线路】机器学习线路概述与内容关键点说明
  • 解决 Spring Boot 对 Elasticsearch 字段没有小驼峰映射的问题
  • STC8G 8051内核单片机开发(GPIO)
  • “Payload document size is larger than maximum of 16793600.“问题解决(MongoDB)
  • C++ 网络编程(14) asio多线程模型IOThreadPool
  • PyTorch 安装使用教程
  • EXCEL小妙招——判断A列和B列是否相等
  • AI时代SEO关键词策略
  • cv610将音频chn0配置为g711a,chn1配置为 aac编码,记录
  • Java 大视界 -- Java 大数据机器学习模型在自然语言处理中的跨语言信息检索与知识融合(331)
  • Docker:容器化技术的基石与实践指南