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

RPC 与http对比

RPC 调用全流程深度解析

一、核心流程总览

一次完整的 RPC 调用包含以下关键步骤,其完整生命周期如下图所示:

二、详细步骤解析

阶段一:客户端初始化调用

步骤 1: 客户端应用发起调用

python

# 程序员编写的代码
user = user_service_stub.GetUser(123)
  • 开发者调用客户端存根提供的方法

  • 感受:完全像调用本地函数一样简单

阶段二:客户端序列化与编码

步骤 2: 参数序列化(打包)

  • 客户端存根捕获方法名(GetUser)和参数(123)

  • 将参数序列化为协议缓冲区格式

  • 生成包含方法名和序列化参数的请求消息

步骤 3: 编码为二进制流

  • 使用 Protobuf 将文本数据编码为紧凑的二进制格式

  • 二进制数据体积比 JSON 小 3-10 倍

阶段三:网络传输

步骤 4: 建立网络连接

  • 客户端通过 TCP 连接连接到服务器端

  • gRPC 默认使用 HTTP/2,支持多路复用

步骤 5: 发送请求数据

  • 二进制数据通过网络发送到服务器

  • 请求头包含服务名、方法名和超时设置等信息

阶段四:服务端处理

步骤 6: 服务端接收请求

  • 服务端存根监听指定端口

  • 接收传入的二进制数据流

步骤 7: 解码与反序列化

  • 解码二进制数据为结构化消息

  • 提取方法名(GetUser)和参数(123)

步骤 8: 方法分发与执行

python

# 服务端存根根据方法名路由到实际实现
if method_name == "GetUser":result = actual_get_user_implementation(user_id)
  • 服务端存根找到对应的业务逻辑方法

  • 使用反序列化后的参数调用该方法

步骤 9: 业务逻辑执行

  • 执行真正的业务逻辑(数据库查询、计算等)

  • 生成原始结果数据

阶段五:响应返回

步骤 10: 结果序列化

  • 将业务逻辑返回的结果序列化为 Protobuf 格式

  • 编码为二进制格式准备网络传输

步骤 11: 发送响应

  • 通过同一连接将二进制响应发送回客户端

  • 包含状态码(成功/失败)和序列化后的结果

阶段六:客户端处理响应

步骤 12: 接收并解码响应

  • 客户端存根接收二进制响应

  • 解码 Protobuf 数据为结构化对象

步骤 13: 返回最终结果

python

# 客户端存根将结果返回给应用程序
return deserialized_user_object
  • 应用程序获得最终结果,完全不知道背后的网络通信

三、RPC 与 HTTP 的深度对比

3.1 设计哲学差异

特性HTTP/RESTfulRPC
思维模式资源操作 (操作名词)方法调用 (调用动词)
通信协议HTTP/1.1 + 文本(JSON/XML)自定义协议 + 二进制(Protobuf/Thrift)
接口定义松散契约,依赖文档强契约,IDL接口定义语言
耦合性松散耦合紧密耦合
性能相对较低,文本解析慢较高,二进制效率高
可读性高,人类可读低,二进制不可读
调试难度简单,浏览器可直接调试复杂,需要专用工具

3.2 协议效率对比

python

# HTTP/JSON 请求示例
POST /api/users HTTP/1.1
Host: api.example.com
Content-Type: application/json
Content-Length: 56{"name": "Alice", "email": "alice@example.com"}# gRPC/Protobuf 请求示例(二进制格式,不可读但高效)
# 方法名: UserService.CreateUser
# 参数: 0x0a05416c696365120f616c696365406578616d706c652e636f6d
  • HTTP/JSON:文本协议,头部庞大,解析需要字符串处理

  • gRPC:二进制协议,头部紧凑,解析速度快3-10倍

四、RPC 的适用场景

4.1 推荐使用 RPC 的场景

✅ 内部微服务通信

  • 服务间需要高性能通信

  • 服务由同一团队或紧密协作的团队维护

  • 例如:订单服务调用用户服务获取用户信息

✅ 高性能要求的系统

  • 高并发、低延迟场景

  • 大数据量传输需求

  • 例如:实时数据处理系统、金融交易系统

✅ 同构技术栈环境

  • 服务端使用相似的技术栈

  • 能够统一维护接口定义

  • 例如:全Java或全Go的微服务生态系统

✅ 需要强类型约束的项目

  • 大型项目需要编译期检查

  • 减少运行时错误

  • 例如:核心业务系统、基础设施服务

4.2 不建议使用 RPC 的场景

❌ 对外公开API

  • 需要支持多种客户端类型

  • 第三方开发者使用

  • 例如:公共开放平台API

❌ 快速原型开发

  • 需要快速迭代和变更

  • 接口稳定性不高

  • 例如:创业项目MVP阶段

❌ 浏览器前端直接调用

  • 需要广泛的浏览器兼容性

  • 调试和测试便利性重要

  • 例如:Web应用前端

五、为什么不建议在前端直接使用 RPC

5.1 技术限制与兼容性问题

  • 协议不兼容:浏览器只能使用 HTTP/1.1,而 gRPC 基于 HTTP/2

  • 需要额外代理:必须部署 gRPC-Web 代理进行协议转换

  • 增加架构复杂度:额外组件意味着更多运维成本和故障点

5.2 开发与调试体验差

javascript

// HTTP调试 - 简单直观
// 直接在浏览器中测试
fetch('/api/users/123').then(response => response.json()).then(data => console.log(data));// gRPC-Web调试 - 复杂困难
// 需要专用工具和知识
const client = new UserServiceClient('https://api.example.com');
const request = new GetUserRequest();
request.setUserId(123);
client.getUser(request, (err, response) => {console.log(response.toObject());
});
  • 调试工具缺乏:浏览器开发者工具无法直接解析二进制协议

  • 错误处理复杂:需要了解 gRPC 特定错误码和状态

  • 学习成本高:前端开发者需要学习新的概念和工具链

5.3 生态系统不成熟

方面HTTP/RESTfulgRPC-Web
测试工具Postman, Insomnia, Curl专用gRPC客户端
监控调试Chrome DevTools, 各种插件有限的支持
缓存机制HTTP缓存头, CDN需要自定义实现
浏览器支持原生支持需要额外库

5.4 团队协作挑战

  • 前后端强耦合:接口变更需要前后端同时更新

  • 版本管理困难:需要严格的proto文件版本控制

  • 部署协调复杂:前后端必须同步部署,违背了前后端分离原则

5.5 性能收益有限

python

# 对于典型Web应用,性能提升不明显
# 小数据请求:HTTP/JSON 15ms vs gRPC 12ms
# 大数据请求:HTTP/JSON 150ms vs gRPC 100ms# 但增加了架构复杂度和开发成本
# 大多数Web应用的数据传输量不大,HTTP性能足够

六、现代架构的最佳实践

6.1 混合架构模式

text

[浏览器前端] → HTTP/RESTful → [API网关] → RPC/gRPC → [内部微服务]

6.2 各层职责划分

  1. 前端层:使用 HTTP/RESTful,保持兼容性和可调试性

  2. 网关层:负责协议转换、认证、限流和日志

  3. 内部服务层:使用 RPC/gRPC,享受高性能和强类型优势

6.3 实际部署示例

python

# API网关示例(Node.js)
app.post('/api/users', async (req, res) => {// 1. 认证和验证const auth = authenticate(req.headers.authorization);// 2. 转换为gRPC调用const request = new CreateUserRequest();request.setName(req.body.name);request.setEmail(req.body.email);try {// 3. 调用内部gRPC服务const response = await userServiceClient.createUser(request);// 4. 转换回HTTP响应res.json({ id: response.getId(), name: response.getName() });} catch (error) {// 5. 错误处理转换res.status(grpcToHttpError(error.code)).json({ error: error.message });}
});

七、总结与决策指南

7.1 技术选型决策流程

  1. 是对外API还是内部调用?

    • 对外 → HTTP/RESTful

    • 内部 → 考虑RPC

  2. 性能要求是否极高?

    • 是 → RPC

    • 否 → HTTP可能足够

  3. 团队能否维护接口一致性?

    • 能 → RPC

    • 不能 → HTTP

  4. 是否需要浏览器直接调用?

    • 是 → HTTP

    • 否 → 可以考虑RPC

7.2 核心建议

  • 内部微服务通信:优先选择 gRPC 等 RPC 框架

  • 对外公开API:使用 HTTP/RESTful

  • 浏览器前端:坚持使用 HTTP/RESTful,通过API网关连接内部RPC服务

  • 混合架构:在现代分布式系统中是最佳实践

7.3 学习路径建议

  1. 掌握 Protobuf 语法和接口定义

  2. 学习一种 RPC 框架(gRPC 推荐)

  3. 理解网络编程和序列化原理

  4. 掌握API网关设计和实现

  5. 学习分布式系统设计模式

通过合理运用 RPC 和 HTTP 的各自优势,可以构建出既高性能又易于维护的现代分布式系统。


文章转载自:

http://hjeTOY5a.gctgc.cn
http://lSh4nHPo.gctgc.cn
http://MWIQKLJ1.gctgc.cn
http://RicVmK8a.gctgc.cn
http://OV6ALmNZ.gctgc.cn
http://CpKovL5B.gctgc.cn
http://UQUOOVWp.gctgc.cn
http://vTxfUkDD.gctgc.cn
http://8YuvVzLq.gctgc.cn
http://URjIhLKu.gctgc.cn
http://GX81ImS5.gctgc.cn
http://JHIYSyRw.gctgc.cn
http://g0llA3Xr.gctgc.cn
http://NYKlvjJR.gctgc.cn
http://IxTbtcaP.gctgc.cn
http://hp0mqWn6.gctgc.cn
http://tsSLBCJv.gctgc.cn
http://ZvkZXSkv.gctgc.cn
http://yo5Gil0f.gctgc.cn
http://2PYdpMXa.gctgc.cn
http://3WgfjVry.gctgc.cn
http://ljgrMgzl.gctgc.cn
http://QQ2IvQlg.gctgc.cn
http://PJCsOHJX.gctgc.cn
http://0ICY5JGV.gctgc.cn
http://uowbJggI.gctgc.cn
http://W0tJCWZG.gctgc.cn
http://lDTs3xiU.gctgc.cn
http://ySPGeJIY.gctgc.cn
http://FSQ8Nb7j.gctgc.cn
http://www.dtcms.com/a/375394.html

相关文章:

  • OpenEuler安装gitlab,部署gitlab-runner
  • 电池热管理新突破!《Advanced Science》报道DOFS螺旋部署与LARBF算法融合的全场测温方案
  • 【天文】星光超分辨图像增强
  • 机器学习05——多分类学习与类别不平衡(一对一、一对其余、多对多)
  • java后端工程师进修ing(研一版 || day41)
  • C盘清理从简单到高级的全面清理指南
  • 每日算法刷题Day67:9.9:leetcode bfs10道题,用时2h30min
  • PCL 基于法向量进行颜色插值赋色
  • 四数之和
  • MySql案例详解之事务
  • golang 语言核心
  • 【项目】在AUTODL上使用langchain实现《红楼梦》知识图谱和RAG混合检索(二)RAG部分
  • 安卓学习 之 贞布局FrameLayout
  • 【ISP】Charlite工具实操
  • IntelliJ IDEA断点调试全攻略
  • OceanBase存储过程基本使用
  • 使用 OBD 交互式部署单点OceanBase数据库
  • 内存管理这一块
  • 【深度学习新浪潮】什么是具身智能?
  • Linux tc 常用命令总结(网卡限速、延迟、丢包与整形)
  • Windows 命令行:路径末端的反斜杠
  • Shell脚本编程基本认识
  • Redis 面试
  • 大学地理信息科学该如何学习才能好就业
  • 浅谈“SVMSPro视频切片”技术应用场景
  • OpenHarmony多模输入子系统全链路剖析:从HCS配置到HDI芯片驱动源码深度解读
  • 1. linux 下qt 应用开机自启,需要sudo时
  • QML中的Popup
  • Cursor Pro试用
  • shell介绍