讲师中心 微信公众号
AI工具推荐 视频效率加速

C++如何构建一个支持自定义协议的RPC远程过程调用框架?(后端架构)

胖晨吖_2623

胖晨吖_2623

发布时间:2026-03-09 13:04:03

|

449人浏览过

|

来源于php中文网

原创

选 protobuf 为序列化协议最稳妥,因其跨语言支持好、IDL 易维护、C++ 零拷贝友好;需开启 optional/oneof 保证兼容性,禁用裸指针与 STL 容器,改用 repeated 字段。

c++如何构建一个支持自定义协议的rpc远程过程调用框架?(后端架构)

怎么选序列化协议才不卡在跨语言和性能上

自定义 RPC 框架里,序列化不是“能跑就行”,而是决定你后续能不能加 Go/Python 服务、压测时 latency 突然翻倍的根源。别一上来就手写二进制格式——protobuf 是当前最稳妥的起点,它生成的 C++ 代码零拷贝友好、ParseFromString 和 SerializeToString 接口稳定、IDL 易维护;flatbuffers 虽快但 C++ 运行时依赖 schema,调试时看不到原始字段名,上线后改个字段容易 silently 失败。

常见错误现象:Deserialize failed: invalid wire type,往往是 client 用新版 proto 发请求,server 还在用旧版头文件编译,没做 forward/backward 兼容校验。

  • 必须开启 proto2 的 optional 或 proto3 的 oneof 来控制字段可选性,避免默认值污染语义
  • 禁止在 message 里嵌套裸指针或 STL 容器(如 std::vector<int></int>),一律用 repeated 字段,否则序列化结果不可控
  • 如果真要极致性能且只跑 C++,可以后期用 capnproto 替换,但它不支持浮点数 NaN 校验,线上遇到 NaN 会直接 abort

如何让网络层不成为吞吐瓶颈

很多人用 boost::asio 写完 accept + async_read 就以为搞定了,结果 QPS 上不去还查不出原因。根本问题是没把连接生命周期和业务线程解耦:每个 connection 对应一个 io_context 实例?错,应该共享一个或少数几个 io_context,再配固定数量的 thread_pool 去 dispatch 请求。

典型坑:async_read 回调里直接调用耗时函数(比如数据库查询),导致整个 io_context 被 block,后续所有连接卡住。

立即学习“C++免费学习笔记(深入)”;

C++14
C++14

C++14 对 C++11 的修正与增强版本,适合旧系统维护和较老工具链兼容。

下载
  • 收包后立即用 post 把解析+处理逻辑扔进业务线程池,io_context 只管 I/O
  • 包头必须带长度字段,用 async_read 先读 4 字节再读 body,别用 delimiter(比如 \n)——HTTP/2 都不用换行分隔了
  • 禁用 Nagle 算法:socket.set_option(tcp::no_delay(true)),否则小包延迟飙升

怎样设计请求 ID 和超时机制才不会丢响应

RPC 最怕“发出去没回音”,表面是网络问题,实际常因 request_id 重复或 timeout 清理策略不对。C++ 里不能靠全局递增 int——多线程下 ++g_req_id 不安全,也不能用 std::chrono::steady_clock::now().time_since_epoch().count() 当 ID,纳秒级时间戳在高并发下极易碰撞。

正确做法是组合:线程局部 ID + 时间戳低 32 位 + 随机 salt。例如 uint64_t req_id = (tid 。

  • 每个 rpc_client 实例维护自己的 std::unordered_map<uint64_t std::promise>></uint64_t>,key 就是这个 req_id
  • 发送前插入 map,同时启动 std::thread 或 timer(推荐 asio::steady_timer)等待 timeout,超时则 promise.set_exception
  • 收到响应后先查 map,存在就 set_value 并 erase;不存在说明已超时,直接丢弃——别试图重试,重试逻辑应在上层业务控制

为什么服务发现和负载均衡不能硬编码在 client 里

本地测试时写死 "127.0.0.1:8080" 很方便,但上线后节点扩缩、故障转移、灰度发布全崩。C++ 没有像 Java 那样成熟的注册中心 SDK,得自己对接 etcd 或 consul 的 HTTP API,但千万别每发一次请求都去查一次服务列表。

真实场景下,client 启动时拉取一次全量节点,存进 std::vector<endpoint></endpoint>,再用后台线程定期 GET /v1/health 做健康检查,剔除失联节点。负载策略选 round_robin 就够用,别一上来搞一致性哈希——C++ 里 std::hash<:string></:string> 在不同编译器版本可能不一致,导致同一 key 路由到不同 server。

  • etcd watch 接口要用 long polling,别轮询,否则集群压力大
  • 节点 IP+端口字符串作为 key 存进 map,不要用 struct sockaddr_in 直接 hash,字节序和 padding 会导致跨平台不一致
  • 首次连接失败时,别立刻 panic,应 fallback 到本地缓存的节点列表(哪怕过期 30 秒),保证降级可用

真正难的不是写通一个 call,而是当 client 同时发起 10k 并发、server 有 50 个实例、其中 3 个正在滚动更新、etcd 网络抖动 200ms 时,你的 timeout 设置、重试次数、连接复用策略是否还能让 P99 延迟稳定在 50ms 内——这些细节,往往在压测最后一天才暴露。

热门AI工具

更多
Laper
Laper Hot

Laper是专为编剧、导演和制片人推出的 AI 原生剧本创作工具。

SkildArt
SkildArt Hot

SkildArt是一款AI文本写作工具,一站式 AI 视觉创作平台。

DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

VibeKnow
VibeKnow Hot

一款AI视频创作工具,主要用于全球首个AI知识视频创作平台,文档、文章、网页,一键生成视频,适合需要提升相关任务效率的用户。

讯飞智作

讯飞智作是一款AI视频创作工具,AI文本配音工具,数字人课程、营销视频制作。

AionClaw
AionClaw Hot

AionClaw是一款面向办公、创作和编程任务的AI桌面智能体。

WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

Atoms
Atoms Hot

Atoms是一款AI智能体工具,第一支自动构建真实业务的 AI 团队。

相关专题

更多
counta和count的区别
counta和count的区别

Count函数用于计算指定范围内数字的个数,而CountA函数用于计算指定范围内非空单元格的个数。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

3348

2023.11.20

string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

6659

2023.08.02

int占多少字节
int占多少字节

int占4个字节,意味着一个int变量可以存储范围在-2,147,483,648到2,147,483,647之间的整数值,在某些情况下也可能是2个字节或8个字节,int是一种常用的数据类型,用于表示整数,需要根据具体情况选择合适的数据类型,以确保程序的正确性和性能。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

3225

2024.08.29

c++怎么把double转成int
c++怎么把double转成int

本专题整合了 c++ double相关教程,阅读专题下面的文章了解更多详细内容。

4168

2025.08.29

C++中int的含义
C++中int的含义

本专题整合了C++中int相关内容,阅读专题下面的文章了解更多详细内容。

2845

2025.08.29

C++ 智能指针与现代内存管理
C++ 智能指针与现代内存管理

深入讲解 C++ 现代内存管理的核心工具——智能指针,涵盖 unique_ptr 独占所有权语义、shared_ptr 引用计数机制与循环引用问题、weak_ptr 弱引用的应用场景、make_unique/make_shared 工厂函数的性能优势、自定义删除器的编写、RAII 资源管理思想的实践,以及从裸指针迁移到智能指针的重构策略,帮助开发者编写安全无泄漏的现代 C++ 代码。

379

2026.04.23

硬盘接口类型介绍
硬盘接口类型介绍

硬盘接口类型有IDE、SATA、SCSI、Fibre Channel、USB、eSATA、mSATA、PCIe等等。详细介绍:1、IDE接口是一种并行接口,主要用于连接硬盘和光驱等设备,它主要有两种类型:ATA和ATAPI,IDE接口已经逐渐被SATA接口;2、SATA接口是一种串行接口,相较于IDE接口,它具有更高的传输速度、更低的功耗和更小的体积;3、SCSI接口等等。

3168

2023.10.19

PHP接口编写教程
PHP接口编写教程

本专题整合了PHP接口编写教程,阅读专题下面的文章了解更多详细内容。

5049

2025.10.17

Gradle插件开发入门教程
Gradle插件开发入门教程

本专题介绍Gradle插件开发的基本流程,涵盖插件类编写、自定义任务注册、扩展参数设计和插件应用方法,帮助你理解插件如何组织构建逻辑,减少多个项目之间的重复配置。

60

2026.10.22

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
LLVM官方文档
LLVM官方文档

共0课时 | 0人学习

Memcheck使用手册
Memcheck使用手册

共0课时 | 0人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn