RPC详解
一、 RPC 是什么RPC 全称Remote Procedure Call远程过程调用。它让一个进程像调用本地函数一样调用另一台机器或另一个进程中的函数。本地调用int result calculator.add(3, 5);RPC 调用看起来可能完全一样int result calculatorClient.add(3, 5);但背后实际发生的是客户端程序 ↓ 参数序列化 网络请求 ↓ 服务端接收请求 ↓ 参数反序列化 执行 add(3, 5) ↓ 结果序列化 网络响应 ↓ 客户端反序列化 ↓ 得到结果 8RPC 的核心目标是屏蔽网络通信、序列化和服务定位等细节为调用者提供接近本地函数调用的编程体验。但必须注意远程调用永远不等于本地调用。远程调用可能超时、丢包、重复执行、服务不可用。二、 一个 RPC 调用的完整过程假设客户端调用UserService.getUser(1001)第一步调用客户端代理客户端通常不会直接操作 Socket而是调用生成或封装好的代理对象User user userServiceClient.getUser(1001);这个代理对象一般称为Client StubClient Proxy客户端存根客户端代理它看起来实现了UserService接口实际工作是构造网络请求。第二步构造 RPC 请求请求通常包含{ requestId: abc-123, service: UserService, method: getUser, parameterTypes: [long], arguments: [1001] }常见字段包括字段作用requestId关联请求和响应service要调用的服务method要调用的方法arguments方法参数metadataToken、链路信息、版本等deadline请求最晚完成时间第三步序列化请求对象不能直接通过网络发送需要转换成字节RPC请求对象 → 字节数组这个过程称为序列化。常见序列化方式JSONXMLProtocol BuffersMessagePackThrift Binary Protocol自定义二进制协议JSON 可读性好但体积通常更大、解析更慢。Protocol Buffers 等二进制格式通常更紧凑也更适合高性能 RPC。第四步编码成网络消息只有序列化还不够。TCP 是字节流没有天然的“消息边界”。假设连续发送两条消息消息Ahello 消息Bworld接收端可能一次读到helloworld也可能分成hel lowor ld因此 RPC 协议通常需要定义消息帧-------------------------------------------------- | 魔数 | 版本号 | 消息类型 | 数据长度 | 消息体 | --------------------------------------------------其中“数据长度”可以帮助接收端解决 TCP 粘包和拆包问题。第五步发送请求客户端通过网络协议发送请求底层可能使用TCPHTTP/1.1HTTP/2HTTP/3QUICUnix DomainSocket因此RPC 是一种调用模型不是某一种固定的网络协议。例如 gRPC 通常使用 HTTP/2但 RPC 并不等于 HTTP/2。第六步服务端分发请求服务端收到请求后解析出服务名UserService 方法名getUser 参数1001然后通过方法映射找到具体实现UserService service serviceRegistry.get(UserService); User result service.getUser(1001);这部分通常由 Server Stub、Dispatcher 或 Handler 完成。第七步返回响应服务端执行完方法后构造响应{ requestId: abc-123, status: OK, result: { id: 1001, name: Alice } }如果执行失败则可能返回{ requestId: abc-123, status: ERROR, errorCode: USER_NOT_FOUND, message: User does not exist }客户端通过requestId将响应交给等待中的调用。三、 RPC 框架由哪些部分组成一个完整的 RPC 框架通常包括以下模块。客户端代理把本地方法调用转换成 RPC 请求userService.getUser(1001)转换为serviceUserService methodgetUser arguments[1001]动态代理、代码生成和字节码增强都可以实现客户端代理。序列化器负责对象和字节之间的转换对象 → 字节序列化 字节 → 对象反序列化序列化不仅影响性能也影响跨语言能力和协议兼容性。网络传输层负责建立和复用连接发送与接收数据编解码心跳检测流量控制TLS 加密高性能 RPC 框架一般使用连接池或长连接不会每次调用都重新建立 TCP 连接。服务注册与发现客户端需要知道服务端地址。简单情况下可以写死UserService → 10.0.0.8:8080但实际系统通常有多个实例UserService: - 10.0.0.8:8080 - 10.0.0.9:8080 - 10.0.0.10:8080服务端启动时注册地址客户端查询可用实例。这就是服务注册与发现。负载均衡器客户端发现多个实例后需要选择其中一个随机轮询加权轮询最少活跃调用一致性哈希基于延迟选择基于区域或机房选择RPC 中常见的是客户端负载均衡客户端自己选择服务实例。服务端分发器根据服务名和方法名找到具体代码(UserService, getUser) → UserServiceImpl.getUser()容错模块负责处理超时重试熔断限流降级故障节点摘除可观测性模块通常记录请求耗时成功率错误码调用链 Trace请求数量 QPS超时次数重试次数上下游服务关系四、 IDL 与代码生成跨语言 RPC 框架通常使用 IDL即接口定义语言。以类似 Protocol Buffers 的写法为例message GetUserRequest { int64 user_id 1; } message User { int64 id 1; string name 2; } service UserService { rpc GetUser(GetUserRequest) returns (User); }框架可以根据 IDL 生成Java 客户端代码 Go 服务端代码 Python 数据结构 TypeScript 类型定义这样 Java 客户端可以调用 Go 服务端而不需要双方手写网络协议。IDL 的价值包括明确服务接口提供强类型约束自动生成客户端和服务端代码支持多语言帮助维护协议兼容性五、RPC 的调用类型一元调用一个请求对应一个响应Client ──Request── Server Client ─Response── Server例如getUser(userId) → User单向调用客户端只发送请求不等待业务响应Client ──Request── Server适合日志、通知等场景但不能简单理解为“请求一定成功”。服务端流式调用客户端发送一个请求服务端不断返回数据Client ──Request── Server Client ─Data 1──── Server Client ─Data 2──── Server Client ─Data 3──── Server例如持续接收股票价格或大模型输出。客户端流式调用客户端持续发送数据服务端最终返回一个结果Client ──Chunk 1── Server Client ──Chunk 2── Server Client ──Chunk 3── Server Client ─Result──── Server例如上传大文件。双向流式调用双方可以独立、持续地发送数据Client ══════════ Server适合实时协作、聊天、游戏和持续事件传输。六、 同步、异步与 Future同步调用User user client.getUser(1001);当前线程等待响应逻辑简单但等待期间可能阻塞线程。异步调用FutureUser future client.getUserAsync(1001); // 执行其他工作 User user future.get();也可以使用回调client.getUserAsync(1001, user - { System.out.println(user); });或者使用协程val user userClient.getUser(1001)代码看起来同步但底层线程不一定被阻塞。七、 RPC 最关键的问题失败语义本地方法要么返回要么抛异常。远程调用的状态更复杂。假设客户端请求扣款等待响应时超时客户端 ──扣款100元── 服务端 客户端 ──响应── 服务端客户端超时后无法确定请求根本没有到达服务端请求到达了但尚未执行扣款已经完成但响应丢失服务端执行时发生了部分失败。所以 RPC 经常具有这种不确定性客户端不知道操作究竟没有执行还是已经执行但响应没有回来。这也是分布式系统比本地程序困难的重要原因。八、超时、重试与幂等性超时每次 RPC 都应该有超时或截止时间调用最长允许 500ms否则线程和连接可能无限等待最终拖垮整个系统。相比每一层独立设置固定超时传播统一的deadline通常更合理请求总期限12:00:01.500下游服务根据剩余时间决定是否继续处理。重试以下错误可能适合重试临时网络故障服务短暂不可用连接被重置某些限流或过载错误但重试会增加系统压力通常需要最大重试次数 指数退避 随机抖动例如第1次等待100ms 第2次等待200ms 第3次等待400ms幂等性如果同一个请求执行多次最终效果与执行一次相同就称为幂等。天然幂等查询用户 把状态设置为“已关闭” 删除编号为 100 的记录通常不天然幂等余额增加 100 元 创建一个新订单 发送一张优惠券对于非幂等操作可以加入唯一请求号idempotencyKey payment-20260724-0001服务端记录已经处理过的请求避免重试导致重复扣款或重复创建订单。九、 RPC 与 HTTP、REST 的关系RPC 和 HTTP 不是同一层面的概念RPC 描述“像调用函数一样调用远程服务”HTTP 是应用层通信协议REST 是一种围绕资源设计接口的架构风格REST 风格GET /users/1001 POST /orders DELETE /orders/2001RPC 风格UserService.GetUser(1001) OrderService.CreateOrder(...) OrderService.CancelOrder(2001)RPC 可以建立在 HTTP 上。例如 gRPC 使用 HTTP/2 承载 RPC 消息。方面RPCREST核心抽象方法、服务资源接口形式CreateOrder()POST /orders类型约束通常较强取决于规范浏览器兼容可能需要适配通常较好内部服务通信很适合也可使用调试可读性二进制协议较弱JSON 通常较直观流式通信部分框架原生支持需要 SSE、WebSocket 等RPC 更适合强调内部方法调用和强类型契约的系统REST 常用于开放 API、浏览器 API 和资源化接口。十、 熔断、限流与服务雪崩假设服务调用链为订单服务 → 库存服务 → 商品服务 → 数据库商品服务变慢后库存服务的请求开始堆积库存服务变慢又会拖住订单服务最终导致整个系统资源耗尽这就是服务雪崩。常见保护机制限流限制单位时间内的请求数量熔断失败率过高时暂时停止调用降级返回缓存值或简化结果隔离不同服务使用独立线程池或连接池背压下游处理不过来时通知上游减速负载卸载系统过载时快速拒绝部分请求熔断器通常有三个状态Closed正常调用 Open快速失败不再访问故障服务 Half-Open允许少量请求探测服务是否恢复十一、RPC 的性能成本一次本地函数调用可能只需纳秒级到微秒级而 RPC 通常需要经历代理调用 → 请求对象创建 → 序列化 → 排队 → 网络传输 → 服务端解码 → 线程或协程调度 → 业务处理 → 响应序列化 → 网络返回 → 客户端解码优化方向包括使用紧凑的二进制序列化复用连接减少不必要的字段批量请求使用异步 I/O避免过细的服务接口减少跨服务调用次数合理设置压缩阈值控制日志和链路追踪开销例如不要设计成查询用户名 → 1次 RPC 查询头像 → 1次 RPC 查询会员等级 → 1次 RPC 查询账户状态 → 1次 RPC可以考虑合并成getUserProfile() → 1次 RPC但接口也不能无限膨胀需要根据业务边界权衡。

相关新闻

AMD Ryzen处理器深度调试指南:5个核心技巧掌握硬件级性能调优

AMD Ryzen处理器深度调试指南:5个核心技巧掌握硬件级性能调优

AMD Ryzen处理器深度调试指南:5个核心技巧掌握硬件级性能调优 【免费下载链接】SMUDebugTool A dedicated tool to help write/read various parameters of Ryzen-based systems, such as manual overclock, SMU, PCI, CPUID, MSR and Power Table. 项目地址: htt…

2026/7/24 20:28:37阅读更多 →
数据结构:跳表

数据结构:跳表

一、跳表是什么跳表(Skip List)是一种支持快速查找、插入和删除的有序数据结构。它的底层仍然是链表,但额外建立了多层“索引链表”,让查找时可以跳过大量节点。可以把它理解成:普通链表:逐个节点寻找跳表&…

2026/7/24 20:28:37阅读更多 →
DalinX V12 三支柱落地实录:如何做到 C6=0、C2/C12 逐位不变的同时 C11 提升 +49%

DalinX V12 三支柱落地实录:如何做到 C6=0、C2/C12 逐位不变的同时 C11 提升 +49%

作者: 贾大林(Dalin Jia) 石家庄 项目: QN1 幻化引擎 DalinX V12 版本: 12.0.0 | 日期: 2026-07-24 声明: 私有非公开,不上 arXiv,git remote 恒空。本文记录 V12 三支柱(OAR / MTM / FAS)架构的完整落地过…

2026/7/24 20:28:37阅读更多 →
国产AI技术发展:算力突破与大模型优化实践

国产AI技术发展:算力突破与大模型优化实践

1. 国产AI技术发展现状与挑战当前全球AI领域正处于快速发展阶段,以GPT为代表的大模型技术引领了新一轮技术革命。在这一背景下,中国AI产业面临着独特的机遇与挑战。从技术层面来看,我国在AI算法研发、应用落地等方面已经取得显著进展&#xf…

2026/7/25 10:59:03阅读更多 →
TikTok美国测试付费短剧APP LimeShorts,或为高ARPU市场付费模式新尝试

TikTok美国测试付费短剧APP LimeShorts,或为高ARPU市场付费模式新尝试

TikTok美国测试付费短剧APP LimeShorts,定价模式多样 据商业内幕报道,TikTok近期在美国测试一款名为LimeShorts的付费短剧APP。用户可选择每周20美元或每年200美元订阅全部内容,也能通过购买虚拟金币按集解锁观看。不过,DataEye研…

2026/7/25 10:59:03阅读更多 →
谷歌Pixel 11呼吸灯设计或引领新潮流,AI时代手机提示灯成刚需?

谷歌Pixel 11呼吸灯设计或引领新潮流,AI时代手机提示灯成刚需?

谷歌Pixel 11新机:呼吸灯设计初亮相近日,谷歌首次公布了Pixel 11系列新机的部分外观设计,确认将配备位于后摄Deco内部的Pixel Glow多彩呼吸灯模组。这一设计旨在实现外观上的差异化和辨识度,在现代手机普遍为全面屏的情况下&#…

2026/7/25 10:59:03阅读更多 →
Unity Spline插件全解析:从核心概念到高级应用与性能优化

Unity Spline插件全解析:从核心概念到高级应用与性能优化

1. 项目概述:为什么你需要一个Spline插件?如果你在Unity里做过任何需要路径、轨迹或连续曲线的功能,比如让角色沿着蜿蜒的小路行走,或者让摄像机平滑地跟随目标,又或者创建一条动态的河流,那你大概率已经和…

2026/7/25 10:59:03阅读更多 →
AI 狂热下软件质量下滑,开发者机遇与挑战并存?

AI 狂热下软件质量下滑,开发者机遇与挑战并存?

诸事不顺,却欢欣鼓舞当编程难题被攻克,为何软件质量每况愈下?作者写下这些文字时,正值 AI 引发的集体狂热时期。人们为获取更多代币奖励,甚至累垮住进医院,急于在一切被自动化取代前分一杯羹。毕竟 AI 模型…

2026/7/25 10:59:03阅读更多 →
CoolProp开源热力学库终极指南:100+种流体数据库完整教程 [特殊字符]

CoolProp开源热力学库终极指南:100+种流体数据库完整教程 [特殊字符]

CoolProp开源热力学库终极指南:100种流体数据库完整教程 🚀 【免费下载链接】CoolProp Thermophysical properties for the masses 项目地址: https://gitcode.com/gh_mirrors/co/CoolProp 你是不是经常为热力学计算而头疼?想要一个既…

2026/7/25 10:57:03阅读更多 →
Go语言静态资源打包方案对比与实践指南

Go语言静态资源打包方案对比与实践指南

1. 项目背景与核心需求在Go语言开发中,我们经常需要处理静态资源文件的打包问题。无论是Web应用的模板文件、前端资源,还是配置文件、证书等,都需要随程序一起分发。传统做法是将这些文件与编译后的二进制文件放在同一目录下,但这…

2026/7/25 1:01:14阅读更多 →
Go语言实现高性能LDAP认证服务的架构与实践

Go语言实现高性能LDAP认证服务的架构与实践

1. 项目背景与核心价值LDAP(轻量级目录访问协议)作为企业级身份认证的黄金标准,已经服务了超过80%的财富500强公司。我在金融科技领域实施统一认证体系时,发现传统Java方案存在启动慢、内存占用高等痛点。而Go语言凭借其协程并发模…

2026/7/25 1:01:14阅读更多 →
【AI面试官实战指南】:用ChatGPT模拟10类高频技术岗面试,3天提升应答精准度92%

【AI面试官实战指南】:用ChatGPT模拟10类高频技术岗面试,3天提升应答精准度92%

更多请点击: https://intelliparadigm.com 第一章:AI面试官实战指南的核心价值与适用场景 AI面试官并非替代人类HR的“黑箱工具”,而是以可解释、可审计、可迭代的方式,赋能招聘全链路的关键基础设施。其核心价值在于将主观经验沉…

2026/7/25 1:01:14阅读更多 →
突破文档下载限制:kill-doc让你看到的都能保存

突破文档下载限制:kill-doc让你看到的都能保存

突破文档下载限制:kill-doc让你看到的都能保存 【免费下载链接】kill-doc 看到经常有小伙伴们需要下载一些免费文档,但是相关网站浏览体验不好各种广告,各种登录验证,需要很多步骤才能下载文档,该脚本就是为了解决您的…

2026/7/25 0:01:16阅读更多 →
C++ string类模拟实现:从深拷贝到内存管理的完整指南

C++ string类模拟实现:从深拷贝到内存管理的完整指南

1. 项目概述:为什么我们要“手撕”string类?在C的学习道路上,尤其是从C语言过渡到C的“初阶”阶段,string类绝对是一个绕不开的核心。标准库里的std::string用起来太方便了,、find、substr,几个操作符和函数…

2026/7/25 0:01:16阅读更多 →
三角洲寻宝鼠工具:高效文件搜索与资源管理实战指南

三角洲寻宝鼠工具:高效文件搜索与资源管理实战指南

1. 先搞清楚“三角洲寻宝鼠”到底是什么工具从名称来看,“三角洲寻宝鼠”更像是一个资源查找或文件检索类工具,而不是游戏或娱乐软件。这类工具的核心价值在于帮助用户快速定位特定资源,比如文档、图片、压缩包或特定格式的文件。如果你经常需…

2026/7/25 0:01:16阅读更多 →
YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

如果你在部署 YOLOv8 时,发现推理速度只有可怜的 1-2 FPS,而别人的演示视频却能跑到 30 FPS 以上,那么问题很可能不在模型本身,而在于你的整个处理链路。很多开发者拿到一个训练好的 YOLOv8 模型后,会直接使用官方示例…

2026/7/24 23:01:03阅读更多 →
Coze与Dify对比指南:低代码AI应用开发从入门到实战

Coze与Dify对比指南:低代码AI应用开发从入门到实战

1. 从零到一:为什么你需要了解 Coze 和 Dify?如果你对 AI 应用开发感兴趣,但一看到“大模型”、“智能体”、“工作流”这些词就头疼,觉得门槛太高,那这篇文章就是为你准备的。很多开发者,包括我自己&#…

2026/7/24 19:00:40阅读更多 →
AI生图工具怎么选?2026年6月版实测对比

AI生图工具怎么选?2026年6月版实测对比

做自媒体的朋友应该都有体会:配图一直是个让人头疼的问题。2026年,AI生图工具已经非常成熟了,但工具太多反而不知道怎么选。以下是截至2026年6月我对主流AI生图工具的实测对比。Midjourney V8.1:速度之王2026年6月11日&#xff0c…

2026/7/24 19:00:40阅读更多 →