0

0

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

穿越時空

穿越時空

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

|

429人浏览过

|

来源于php中文网

原创

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

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

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

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

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

  • 必须开启 proto2optionalproto3oneof 来控制字段可选性,避免默认值污染语义
  • 禁止在 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++免费学习笔记(深入)”;

面多多
面多多

面试鸭推出的AI面试训练平台

下载
  • 收包后立即用 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,得自己对接 etcdconsul 的 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工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

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

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

203

2023.11.20

string转int
string转int

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

990

2023.08.02

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

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

607

2024.08.29

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

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

314

2025.08.29

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

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

235

2025.08.29

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

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

1876

2023.10.19

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

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

636

2025.10.17

php8.4实现接口限流的教程
php8.4实现接口限流的教程

PHP8.4本身不内置限流功能,需借助Redis(令牌桶)或Swoole(漏桶)实现;文件锁因I/O瓶颈、无跨机共享、秒级精度等缺陷不适用高并发场景。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2382

2025.12.29

JavaScript浏览器渲染机制与前端性能优化实践
JavaScript浏览器渲染机制与前端性能优化实践

本专题围绕 JavaScript 在浏览器中的执行与渲染机制展开,系统讲解 DOM 构建、CSSOM 解析、重排与重绘原理,以及关键渲染路径优化方法。内容涵盖事件循环机制、异步任务调度、资源加载优化、代码拆分与懒加载等性能优化策略。通过真实前端项目案例,帮助开发者理解浏览器底层工作原理,并掌握提升网页加载速度与交互体验的实用技巧。

59

2026.03.06

热门下载

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

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Node.js 教程
Node.js 教程

共57课时 | 13万人学习

CSS3 教程
CSS3 教程

共18课时 | 6.8万人学习

Vue 教程
Vue 教程

共42课时 | 9.3万人学习

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

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号