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

Netty从0到1系列之RPC通信

文章目录

  • RPC技术
  • 一、RPC 的核心目标
  • 二、RPC核心组成部分
  • 三、RPC 通信的完整流程
    • 3.1 客户端调用代理对象
    • 3.2 客户端 Stub 封装请求
    • 3.3 网络传输层发送请求
    • 3.4 服务端 Stub 解析请求
    • 3.5 服务端执行方法并返回结果
    • 3.6 服务端 Stub 封装响应
    • 3.7 客户端接收并处理响应
  • 四、RPC 的关键技术点
    • 4.1 序列化 / 反序列化
    • 4.2 网络传输
    • 4.3 服务注册与发现
    • 4.4 负载均衡
    • 4.5 容错机制
    • 4.6 RPC 完整的工作流程
  • 五、RPC vs HTTP
  • 六、主流rpc框架特点
  • 七、性能优化关键技术
    • 7.1 连接池管理
    • 7.2 异步调用与回调
  • 八、RPC 的核心价值与学习要点


推荐阅读:

【01】Netty从0到1系列之I/O模型
【02】Netty从0到1系列之NIO
【03】Netty从0到1系列之Selector
【04】Netty从0到1系列之Channel
【05】Netty从0到1系列之Buffer(上)
【06】Netty从0到1系列之Buffer(下)
【07】Netty从0到1系列之零拷贝技术
【08】Netty从0到1系列之整体架构、入门程序
【09】Netty从0到1系列之EventLoop
【10】Netty从0到1系列之EventLoopGroup
【11】Netty从0到1系列之Future
【12】Netty从0到1系列之Promise
【13】Netty从0到1系列之Netty Channel
【14】Netty从0到1系列之ChannelFuture
【15】Netty从0到1系列之CloseFuture
【16】Netty从0到1系列之Netty Handler
【17】Netty从0到1系列之Netty Pipeline【上】
【18】Netty从0到1系列之Netty Pipeline【下】
【19】Netty从0到1系列之Netty ByteBuf【上】
【20】Netty从0到1系列之Netty ByteBuf【中】
【21】Netty从0到1系列之Netty ByteBuf【下】
【22】Netty从0到1系列之Netty 逻辑架构【上】
【23】Netty从0到1系列之Netty 逻辑架构【下】
【24】Netty从0到1系列之Netty 启动细节分析
【25】Netty从0到1系列之Netty 线程模型【上】
【26】Netty从0到1系列之Netty 线程模型【下】
【27】Netty从0到1系列之Netty ChannelPipeline
【28】Netty从0到1系列之Netty ChannelHandler
【29】Netty从0到1系列之Netty拆包、粘包【1】
【30】Netty从0到1系列之Netty拆包、粘包【2】
【31】Netty从0到1系列之Netty拆包、粘包【3】
【32】Netty从0到1系列之Netty拆包、粘包【4】
【33】Netty从0到1系列之Netty拆包、粘包【5】
【34】Netty从0到1系列之动态从内存分配】
【35】Netty从0到1系列之writeAndFlush原理分析】
【36】Netty从0到1系列之Netty内存管理【上】】
【37】Netty从0到1系列之Netty内存管理【下】】
【38】Netty从0到1系列之Netty内存管理【1】】
【39】Netty从0到1系列之Netty内存管理【2】】
【40】Netty从0到1系列之Netty内存管理【3】】
【41】Netty从0到1系列之Netty内存管理【4】】
【42】Netty从0到1系列之Netty零拷贝技术】
【43】Netty从0到1系列之内置Handler【上】】
【44】Netty从0到1系列之内置Handler【下】】
【45】Netty从0到1系列之基于Netty的开发流程】


RPC技术

RPC(Remote Procedure Call,远程过程调用)是分布式系统中核心的通信技术,它允许一台计算机上的程序(客户端)像调用本地方法一样,调用另一台计算机上的程序(服务端)的方法,屏蔽了底层网络通信的复杂性。其核心价值在于简化分布式系统的开发,让开发者无需关注网络协议、数据传输等细节,专注于业务逻辑。

✅ 1. rpc架构体系

在这里插入图片描述

✅ 2. 动态代理机制

Client CodeDynamic ProxyClient StubNetwork LayeruserService.getUserById(123)JDK动态代理/CGLIB拦截方法调用转RPC请求序列化参数发送网络请求接收响应数据反序列化结果返回结果对象User对象Client CodeDynamic ProxyClient StubNetwork Layer

一、RPC 的核心目标

"像调用本地方法一样调用远程方法"

在单机程序中,方法调用是直接通过内存地址跳转实现的;而在分布式系统中,服务部署在不同机器,必须通过网络传输数据。RPC 的本质是对网络通信的封装,通过一系列机制将 “远程调用” 伪装成 “本地调用”,流程上对开发者透明。

举个例子:

  • 本地调用:int result = calculator.add(1, 2);(直接在进程内执行)
  • 远程调用:同样写int result = calculator.add(1, 2);,但calculator是远程服务的代理,实际通过网络调用另一台机器的add方法。

二、RPC核心组成部分

一个完整的 RPC 框架通常包含 6 个核心模块,协同实现远程调用:

模块作用
客户端(Client)发起远程调用的一方,调用 “代理对象” 的方法。
服务端(Server)提供服务的一方,注册服务并等待客户端调用,执行方法后返回结果。
代理(Stub)客户端的 “替身”,负责将本地方法调用转化为网络请求(序列化参数、组装请求);服务端的 “替身” 负责解析请求、调用本地方法、序列化返回结果。
网络传输层负责底层数据的发送与接收,基于 TCP/UDP/HTTP 等协议,常用 Netty、Mina 等框架实现。
序列化 / 反序列化将内存中的对象(如方法名、参数、返回值)转化为可网络传输的字节流(序列化),或反之(反序列化)。
服务注册与发现管理服务地址(IP: 端口),客户端通过服务名查询可用的服务端地址(如 ZooKeeper、Nacos)。

三、RPC 通信的完整流程

以 " 客户端调用服务端add方法 " 为例

3.1 客户端调用代理对象

客户端通过calculator.add(1, 2)调用的是代理对象(由 RPC 框架自动生成),而非真实的服务端对象。

3.2 客户端 Stub 封装请求

代理对象(客户端 Stub)执行以下操作:

  • 收集调用信息:方法名(add)、参数(1, 2)、参数类型等。
  • 序列化:将这些信息转化为字节流(使用 Protobuf、JSON 等协议)。
  • 组装请求:按 RPC 协议(如自定义协议、gRPC 的 HTTP/2)包装成 “请求包”(含服务名、请求 ID 等元数据)。

3.3 网络传输层发送请求

客户端的网络模块(如 Netty 的 Channel)通过 TCP 连接将请求包发送到服务端。

3.4 服务端 Stub 解析请求

服务端的网络模块接收请求后,交给服务端 Stub 处理:

  • 反序列化:将字节流还原为方法名、参数等对象。
  • 定位服务:根据服务名找到对应的本地实现类(如CalculatorImpl)。

3.5 服务端执行方法并返回结果

服务端 Stub 调用本地方法(CalculatorImpl.add(1, 2)),得到结果(3)。

3.6 服务端 Stub 封装响应

服务端 Stub 将返回结果序列化,按协议组装成 “响应包”(含请求 ID、结果数据),通过网络传输层发回客户端。

3.7 客户端接收并处理响应

客户端网络模块接收响应包,交给客户端 Stub:

  • 反序列化:将字节流还原为返回值(3)。
  • 回调客户端:将结果返回给客户端的调用处(int result = ...)。

整个过程对开发者完全透明,感知不到网络交互的存在。

四、RPC 的关键技术点

4.1 序列化 / 反序列化

数据格式的 "翻译官"

  • 核心需求:高效(小体积、快速度)、兼容(跨语言 / 版本)、安全(防注入)。
  • 常见方案
    • 二进制协议:Protobuf(谷歌,高效、跨语言)、Thrift(Facebook,支持多协议)、Hessian(Java 生态,兼容性好)。
    • 文本协议:JSON(简单、可读性强,但体积大)、XML(冗余度高,逐渐被淘汰)。
  • 选择原则:高性能场景选二进制(如 Protobuf),跨语言且对性能要求不高选 JSON。

序列化与反序列化组件:

协议性能可读性跨语言适用场景
JSONHTTP API, Web应用
Protobuf高性能RPC, 微服务
Thrift跨语言服务
Avro大数据场景
HessianJava间通信

序列化流程:

Java Object
序列化器
字节数组
协议编码
网络包
网络包
协议解码
字节数组
反序列化器
Java Object

4.2 网络传输

数据的 “运输通道”

    • TCP:可靠传输(三次握手、重传机制),适合需要确保数据完整性的场景(如金融交易),是 RPC 的主流选择(Netty 基于 TCP)。
      • UDP:不可靠但速度快,适合实时性要求高的场景(如游戏同步),少数 RPC 框架支持(如自定义 UDP 协议)。
      • HTTP/2:基于 TCP,支持多路复用、头部压缩,gRPC 采用此协议,兼顾兼容性和性能。
  • 连接方式
    • 长连接:客户端与服务端建立一次连接后复用(减少握手开销),适合高频调用(几乎所有 RPC 框架默认采用)。
    • 短连接:每次调用建立新连接(开销大),仅用于低频场景。

4.3 服务注册与发现

服务器的地址簿

  • 核心问题:分布式系统中服务端可能动态扩缩容(IP: 端口变化),客户端如何找到可用服务?
  • 流程
    1. 服务端启动时,将自己的地址(IP: 端口)和服务名注册到注册中心(如 ZooKeeper)。
    2. 客户端启动时,从注册中心订阅服务名对应的地址列表,并缓存到本地。
    3. 服务端下线时,注册中心触发通知,客户端更新本地地址列表。
  • 常见注册中心:ZooKeeper(强一致性,适合高可靠场景)、Nacos(支持 AP/CP 模式,易用性好)、Eureka(Netflix,AP 模式,适合云原生)。

服务注册与发现中心

Service ProviderRegistry CenterService Consumer服务注册阶段注册服务(serviceName, address, metadata)存储服务信息,设置心跳超时注册成功确认服务发现阶段订阅服务变更(serviceName)返回服务实例列表推送服务变更通知服务调用阶段负载均衡选择实例发起RPC调用返回调用结果健康检查阶段发送心跳包更新最后活跃时间loop[定期心跳]Service ProviderRegistry CenterService Consumer

4.4 负载均衡

请求的 “调度员”

  • 核心目标:将客户端请求均匀分配到多个服务端实例,避免单节点过载。
  • 常见策略
    • 轮询(Round Robin):按顺序依次分配(简单,适合服务能力相近的场景)。
    • 权重(Weighted):给性能好的服务端分配更高权重(如配置权重值 3:1)。
    • 一致性哈希(Consistent Hashing):相同参数的请求路由到同一服务端(适合有本地缓存的场景)。
    • 最小活跃数(Least Active):优先分配给处理请求最少的服务端(动态适应负载)。

4.5 容错机制

系统的 “安全阀”

分布式环境中网络波动、服务宕机不可避免,RPC 需要容错机制保证稳定性:

  • 超时重试:请求超时后自动重试(需确保方法幂等性,避免重复执行导致数据错误)。
  • 熔断:当服务端错误率超过阈值时,暂时停止调用(如 10 秒内 50% 请求失败,熔断 30 秒),避免雪崩效应(Netflix Hystrix、Sentinel)。
  • 降级:服务不可用时,返回默认值(如库存查询失败时返回 “暂时无法查询”)。
  • 负载均衡容错:检测到服务端不可达时,自动切换到其他实例(如 Dubbo 的 “失败自动切换”)。

4.6 RPC 完整的工作流程

Client AppClient StubLoad BalancerNetworkServer StubServer AppRegistry Center服务注册启动服务,暴露接口注册服务元数据注册成功服务发现调用远程方法获取服务列表返回可用实例请求负载均衡返回目标实例远程调用序列化请求参数发送RPC请求接收网络数据反序列化请求反射调用实际方法返回执行结果序列化响应数据发送响应接收响应数据反序列化结果返回方法结果健康检查发送心跳确认存活loop[心跳检测]Client AppClient StubLoad BalancerNetworkServer StubServer AppRegistry Center

五、RPC vs HTTP

为什么不直接用 HTTP 接口?

很多人会疑惑:“HTTP 也能实现远程调用,为什么需要 RPC?” 两者的核心区别在于设计目标

维度RPCHTTP(如 RESTful)
定位专为分布式服务调用设计,追求效率和易用性通用协议,适合跨系统(如前端 - 后端)交互
协议复杂度自定义协议(紧凑,如仅包含方法名 + 参数)标准 HTTP 协议(头部冗余,如 Cookie、Host 等)
性能更高(二进制序列化 + 长连接,减少开销)较低(文本序列化 + 头部开销)
易用性客户端直接调用方法,无需拼接 URL 和参数需要手动处理 URL、请求体、响应解析
服务治理内置服务发现、负载均衡、容错等需额外集成(如 Spring Cloud+Eureka)

结论:内部服务间高频调用用 RPC(如微服务架构),跨系统、低频次调用用 HTTP(如开放 API)。

六、主流rpc框架特点

框架特点适用场景
gRPC谷歌开源,基于 HTTP/2 和 Protobuf,跨语言支持好(Java、Go、Python 等),性能优异。跨语言服务调用、高性能场景
Dubbo阿里开源,Java 生态为主,功能丰富(服务发现、负载均衡、熔断等),国内企业广泛使用。Java 微服务架构
ThriftFacebook 开源,支持多语言、多协议(TCP、HTTP),序列化效率高。跨语言、高性能数据传输
Spring Cloud OpenFeign基于 HTTP 的声明式调用,整合 Spring 生态,易用性强。Java 生态,偏好 HTTP 协议的场景

七、性能优化关键技术

7.1 连接池管理

public class ConnectionPool {private final Map<String, List<Channel>> pool = new ConcurrentHashMap<>();private final int maxConnectionsPerAddress;public Channel getConnection(String address) {return pool.compute(address, (addr, channels) -> {if (channels == null) {channels = new ArrayList<>();}// 清理无效连接channels.removeIf(channel -> !channel.isActive());// 创建新连接if (channels.size() < maxConnectionsPerAddress) {Channel newChannel = createChannel(addr);channels.add(newChannel);return newChannel;}// 使用负载均衡策略选择连接return selectChannel(channels);});}
}

7.2 异步调用与回调

public class AsyncRpcCall {public CompletableFuture<User> getUserAsync(Long id) {RpcRequest request = buildRequest(id);RpcFuture<RpcResponse> future = new RpcFuture<>();// 发送异步请求channel.writeAndFlush(request).addListener(f -> {if (!f.isSuccess()) {future.completeExceptionally(f.cause());}});return future.thenApply(response -> {if (response.isSuccess()) {return (User) response.getResult();} else {throw new RpcException(response.getError());}});}
}

八、RPC 的核心价值与学习要点

RPC 的本质是对分布式通信的抽象,通过 “代理 + 序列化 + 网络传输 + 服务治理” 的组合,让远程调用变得简单。要掌握 RPC,需重点理解:

  1. 核心流程:代理如何封装请求、网络如何传输、服务如何发现。
  2. 关键技术:序列化协议的选择、负载均衡策略、容错机制的设计。
  3. 框架实践:结合具体框架(如 Dubbo、gRPC)调试源码,理解其实现细节。
http://www.dtcms.com/a/403086.html

相关文章:

  • Coze源码分析-资源库-创建数据库-后端源码-安全与错误处理
  • LeetCode:52.腐烂的橘子
  • LeetCode算法日记 - Day 52: 求根节点到叶节点数字之和、二叉树剪枝
  • 四种方法解决——力扣189.轮转数组
  • ⸢ 伍-Ⅱ⸥ ⤳ 默认安全治理实践:水平越权检测 前端安全防控
  • 力扣856
  • Leetcode94.二叉数的中序遍历练习
  • 多种解法全解析——力扣217. 存在重复元素
  • 用python做的网站多吗二手书交易网站策划书
  • phpcms网站源码ui培训班多少钱
  • Android Studio 导入 opencv
  • 在线网站做成appdede网站地图样式修改
  • 全新尚界H5凭借HUAWEI XMC数字底盘引擎技术,让湿滑路面也“稳”操胜券
  • iOS 26 性能测试实战,如何评估启动速度、CPUGPU 负载、帧率与系统资源适配(uni-app 与 iOS 原生应用性能方案)
  • 腾讯会议→微课操作
  • html原生表格,实现左侧列固定
  • Idea提高开发效率的快捷键最佳学习方式
  • 做网站一定需要icp么中国建设协会官网
  • Selenium使用教程
  • 多线程——单例模式
  • 镜头调焦的 调整的是焦距还是像距?
  • (四)React+.Net+Typescript全栈(错误处理)
  • @ant-design/icons-vue 打包成多格式库
  • 什么是营销型网站?杭州建设教育网站
  • C++开发环境(VSCode + CMake + gdb)
  • JAVA CodeX精选实用代码示例
  • 肥东网站建设南京医院网站建设
  • Qt 多线程解析
  • ZooKeeper与Kafka分布式:从基础原理到集群部署
  • 免费网站服务器安全软件下载wordpress权限设置方法