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

协程框架高并发翻车了?三个C++ Web框架实测,结果出乎意料

上一版测完总觉得哪里不对,于是改了配置又跑了一遍——这次结果老实多了。

前言:为什么重新测了一遍

这篇文章其实是第二版了。上一篇发出来之后我越想越不对劲——当时每个容器只给了 512MB 内存,fd 上限也没显式调高,跑 10K 并发的时候实际上根本没撑到一万个连接。wrk 报了一堆connect 8983错误,真正建立的有效连接也就一千出头,所谓的"高并发 10K"测试本质上测的还是千级并发。那组数据里 Hical 高并发"遥遥领先"的结论,现在看有水分。

这次我把配置拉满了:每容器1024MB 内存nofile上调到65536,VM 内核参数也做了对应调优(somaxconntcp_max_syn_backlog、端口范围等),确保 wrk 发起的一万个连接能真正建立起来。同时精简了文章的对比范围——压测还是 6 个框架一起跑的(数据完整保留在文章末尾),但本文只聚焦 Hical、Drogon、Cinatra 三个第一梯队选手做深入分析。这三个在上一版常规场景里已经拉开了和其余框架的差距,继续带着 91 QPS 的 cpp-httplib 同框只会让图表失真。

结果确实和上次不一样,尤其是高并发部分的排名翻了个个儿。先把结论放在前面:常规负载下三个框架打得很近,但各自有各自的强项——Hical 在 JSON 和中间件场景领先,Cinatra 在纯吞吐和 JSON Echo 上更快,Drogon 在高并发场景下表现最好。


测试环境

宿主机硬件

项目配置
处理器Intel Core i7-11700K @ 3.60GHz(8核16线程)
内存32 GB
存储SSD(900 GB)
宿主系统Windows 10 Enterprise LTSC 2021

虚拟化环境

项目配置
虚拟化平台Oracle VM VirtualBox 7.1(半虚拟化接口: KVM)
Guest OSUbuntu 24.04.3 LTS Server
VM 分配16 GB RAM / 8 CPU
Docker Engine29.4.3 + Compose v5.1.3
每框架容器4 CPU + 1GB RAM,nofile=65536
压测工具wrk 4.1.0(独立容器),4 线程
默认并发100 连接
持续时间30 秒
编译器GCC 14.2(Ubuntu 24.04)
优化级别Release(-O2)
采样方式每场景连续跑 3 轮,取算术平均值

注:所有框架运行在同一台 VM 的 Docker 容器中,wrk 也在同一 Docker 网络内发起请求(容器间通信,无宿主机网络栈介入)。VirtualBox 虚拟化会引入一定开销,绝对 QPS 数值会低于裸机,但各框架的相对排名通常稳定。

框架版本

框架版本构建方式I/O 模型JSON 库
Hicalv2.6.3复制源码编译C++20 协程 (Boost.Asio)Boost.JSON
Drogonv1.9.8源码编译回调 (Trantor)JsonCpp
CinatralatestFetchContentC++20 协程 (自有实现)iguana

基础场景:Hello World / JSON

先看最简单的纯文本和 JSON 响应,这基本测的是框架自身的"底层开销"——HTTP 解析、路由匹配、响应序列化这些。

场景HicalDrogonCinatra
Hello World (GET /)153,871140,536165,717
JSON 响应 (GET /api/status)141,49995,090128,391
JSON Echo (POST /api/echo)123,58569,343131,440
路径参数 (GET /users/42)140,28586,487125,262

单位:Requests/sec(三轮平均值)

几个观察:

  1. Hello World:三者都在 14w~17w 的水平,Cinatra 166k 略高,Hical 154k,Drogon 141k。Cinatra 和 Hical 差距 8%,属于同一档;Drogon 稍低一些。

  2. JSON 序列化(GET /api/status):Hical 141k 领先,Cinatra 128k 紧随,Drogon 95k 落后较多。这里有个重要背景:Drogon 用的是 JsonCpp 库,而 Hical 用 Boost.JSON,Cinatra 用 iguana。JSON 库本身的性能差异直接体现在这里。

  3. JSON Echo(POST 反序列化+序列化):Cinatra 131k 略快于 Hical 124k,iguana 的反序列化确实快。Drogon 只有 69k,差距比较明显,大概率是 JsonCpp 的开销。

  4. 路径参数:Hical 140k 最高,Cinatra 125k 次之,Drogon 86k 偏低。

小结:不涉及 JSON 的话 Cinatra 最快,一旦碰 JSON 就是 Hical 的地盘。Drogon 吃了 JsonCpp 的亏,不过 Hello World 纯吞吐也就比前两个低 10% 左右,不至于掉队。


中间件场景:真正的分水岭

中间件测试是这次最有意思的部分。为了公平,测试分了两种模式:

  • 原生中间件:Hical 用 RouteGroup 洋葱链,Drogon 用 HttpFilter,Cinatra 因为没有运行时中间件机制,用std::function调用链模拟等价开销。
  • Hical SyncMW:Hical 独有的同步中间件快速路径(全 Sync 时零协程帧,纯栈调用),其他框架继续用各自的原生机制。
场景HicalDrogonCinatra
0 层中间件140,837106,789132,121
3 层(原生)136,302105,171131,595
10 层(原生)93,402104,942137,830
3 层(Hical SyncMW)141,16094,588129,701
10 层(Hical SyncMW)139,685100,652127,711

单位:Requests/sec(三轮平均值)

这里有个很值得讨论的现象:

Hical 的原生异步中间件在 10 层时性能下降明显(从 0 层的 141k 掉到 93k,降幅 34%),而 Drogon 和 Cinatra 几乎不受影响。为什么?因为 Hical 的洋葱模型中间件每层都是一个co_await,10 层就是 10 次协程挂起/恢复 + 10 个协程帧的堆分配。Drogon 的 HttpFilter 是回调链(不走协程),Cinatra 的测试代码是普通函数调用链——人家根本没有协程帧开销。

但这也是为什么 Hical 提供了 SyncMW 快速路径的原因。当所有中间件都使用SyncBeforeHandler且 handler 本身也是同步签名时,RouteGroup 会直接注册为SyncRouteHandler,走dispatchSync()路径——零协程帧,整条链路从中间件到 handler 都是纯栈上函数调用,和 Drogon/Cinatra 的回调/函数调用模型站在同一起跑线上。QPS 从 93k 恢复到 140k,完全消除了协程帧开销,和 0 层中间件的 141k 持平——因为 SyncMW 路径连路由分发本身的协程帧都省了。

公平性说明:Cinatra 在中间件测试中使用的是std::function调用链模拟,而不是框架原生的中间件机制(Cinatra 的 middleware 是编译时模板,不支持运行时动态添加)。这意味着 Cinatra 的中间件数字测的是"函数调用链的开销",而非框架中间件调度本身的开销。这是测试设计上的限制——不同框架的中间件机制差异太大,很难做到 100% 等价对比。


高并发:1000 和 10000 连接

这是最能体现框架"韧性"的测试。

并发连接数HicalDrogonCinatra
100137,522145,663159,519
1,00063,07781,64669,797
10,00059,451100,53463,971

单位:Requests/sec(三轮平均值)

注:10,000 并发时 Cinatra 三轮均出现 timeout(808~2719 个),Hical 第一轮有 1112 个 timeout 后两轮无错误,Drogon 第一轮有 4022 个 timeout 但后两轮几乎为零。

这组数据很有意思:

  • 100 并发:Cinatra 160k 略高,Drogon 146k,Hical 138k。三者差距在 15% 以内。
  • 1000 并发:所有框架都有较大衰减。Drogon 82k 表现最好,Cinatra 70k 次之,Hical 63k。
  • 10000 并发:Drogon 101k 一骑绝尘,是 Hical(59k)和 Cinatra(64k)的 1.6~1.7 倍。

这组结果我没预料到。跑之前我以为 Hical 的 SO_REUSEPORT + 多 io_context 架构在高并发下会有优势,结果被 Drogon 的回调模型按在地上。两个 C++20 协程框架(Hical 和 Cinatra)在 10K 连接下都掉到了 60k 附近,而 Drogon 稳在 101k。协程模型下每个连接维护一个协程帧,一万个帧的管理和调度本身就是开销,Drogon 的回调模型不存在这个问题。

另外要提一嘴:Cinatra 在 10K 时三轮都有数百到数千个 timeout,这也会拖低 QPS。Hical 除了第一轮外零错误但 QPS 同样低,说明瓶颈不在连接管理而在协程调度本身。


延迟对比

除了 QPS,延迟也很重要:

场景Hical AvgDrogon AvgCinatra Avg
Hello World (c=100)1.91 ms1.71 ms1.77 ms
高并发 100014.94 ms12.28 ms15.37 ms
高并发 10000157.22 ms65.86 ms89.80 ms

数据来自 wrk 的 Avg Latency 输出,三轮平均值。

c=100 时三者都在 1.7~1.9ms,没啥好说的。往上拉就有意思了:

  • c=1000:Drogon 12ms,Hical 15ms,Cinatra 15ms——还在一个量级
  • c=10000:Drogon 66ms,Cinatra 90ms,Hical 157ms——Hical 直接拉胯,是 Drogon 的 2.4 倍

和 QPS 数据对得上,高并发就是 Hical 当前最大的短板,后面得好好优化。


资源占用

指标HicalDrogonCinatra
空载内存200.4 MB93.5 MB56.6 MB
满载内存197.0 MB93.5 MB55.8 MB
二进制大小2.1 MB1.9 MB528 KB
代码行数(bench)149 行234 行182 行

Hical 空载就吃了 200 MB,这是 PMR 内存池预分配的代价。好处是运行时几乎不再向系统要内存,坏处是启动就占这么大一坨。Drogon 94 MB,Cinatra 57 MB 最省。

有意思的是三者满载和空载内存几乎没变化——100 并发的压力下连接本身基本不额外吃内存。


综合评价

维度HicalDrogonCinatra
常规吞吐 (c=100)优秀良好优秀
JSON 处理快 (Boost.JSON)慢 (JsonCpp)快 (iguana)
中间件 (少量/SyncMW)最快良好优秀
中间件 (大量,异步)有衰减稳定稳定
高并发 (c=1000+)一般最好良好
高并发延迟偏高最低中等
内存占用高 (200MB)中 (94MB)低 (57MB)
生态成熟度新框架成熟中等

几点坦诚的说明

利益相关:我是 Hical 的作者,这个测试从设计到执行都是我一个人干的。Docker 隔离、相同资源限制、wrk 统一配置——这些我尽力做到了,但屁股决定脑袋,测试设计上的视角偏差肯定有。不服的话欢迎自己跑一遍打我脸。

中间件测试其实不太公平:三个框架的中间件机制完全不一样——Hical 是运行时洋葱链、Drogon 是 HttpFilter 链、Cinatra 压根没有运行时中间件。我尽量模拟等价语义了,但严格说测的不是同一个东西。

关于数据波动:每个场景跑了 3 轮取平均。wrk 在 Docker 里的波动大概 5%~10%,三轮能抹平大部分偶然因素,但不可能完全干净。原始数据附在文末,你可以自己看各轮之间的差异有多大。

双层虚拟化的影响:VirtualBox VM 里跑 Docker,绝对 QPS 肯定比裸机低。但大家都在同一个环境里跑,相对排名应该是稳定的。裸机 Linux 上数字会更好看,不过排名大概率不会变。

选框架不能只看 QPS:Drogon 有完整的 ORM、WebSocket、HTTP 客户端;Cinatra 轻巧好上手;Hical 在中间件和 JSON 这块有些自己的想法。性能测试只是选型的一个参考维度,生态、文档、社区活跃度这些才是长期用下去绕不开的。


复现方法

所有测试代码、Docker 配置和压测脚本均已开源在仓库的benchmark/目录下,详见仓库benchmark/README.md,包含完整的构建、启动、压测、采集和清理流程。

gitclone https://github.com/hical61/hical.gitcdhical/benchmark# 后续步骤参照 benchmark/README.md

注:只需三步就能在你自己的机器上跑出结果。如果和我的数据有明显差异,欢迎开 issue 讨论。


TL;DR

  • 三个框架在 100 并发下性能相近,都在 14w~17w QPS
  • JSON 处理:Hical (Boost.JSON) 和 Cinatra (iguana) 明显快于 Drogon (JsonCpp)
  • 中间件:Hical SyncMW 零协程帧路径最快,但原生异步中间件层数增多时有衰减
  • 高并发 (1000+):Drogon 的回调模型表现最稳健,协程框架都有不同程度下降
  • 内存占用:Cinatra 最低 (57MB),Hical 最高 (200MB,PMR 预分配)
  • 选框架不能只看 QPS,生态和维护同样重要

附录:三轮原始数据

以下是三轮测试的原始 QPS 数据,供交叉验证。每轮为独立的 30 秒 wrk 测试,三轮连续执行,未重启容器。

第一轮(2026-05-25 10:08)

场景HicalDrogonCinatra
Hello World (c=100)156,796.12127,980.96163,774.61
JSON 响应 (c=100)137,491.3674,466.33127,707.87
JSON Echo (c=100)111,098.9162,833.71135,691.72
路径参数 (c=100)150,121.5988,839.01118,966.68
中间件 0 层 (c=100)153,207.23112,848.48136,976.94
中间件 3 层原生 (c=100)136,898.55110,966.38138,247.89
中间件 10 层原生 (c=100)90,629.8290,728.35144,136.85
SyncMW 3 层 (c=100)136,901.79101,765.38124,463.02
SyncMW 10 层 (c=100)141,379.1999,782.52125,834.13
高并发 (c=100)110,907.90125,923.51166,994.13
高并发 (c=1000)62,416.4382,525.5173,922.75
高并发 (c=10000)59,184.0798,286.4670,999.25

高并发 10K Socket Errors: Hical timeout=1112, Drogon timeout=4022, Cinatra timeout=2719

第二轮(2026-05-25 10:55)

场景HicalDrogonCinatra
Hello World (c=100)165,965.45168,045.72165,510.87
JSON 响应 (c=100)145,883.87100,499.66135,568.09
JSON Echo (c=100)131,825.1881,832.00141,118.30
路径参数 (c=100)130,455.3577,424.95126,874.50
中间件 0 层 (c=100)138,603.0599,891.09121,208.64
中间件 3 层原生 (c=100)131,093.7490,841.49126,053.21
中间件 10 层原生 (c=100)93,569.44114,919.03141,083.12
SyncMW 3 层 (c=100)149,265.8580,593.01127,425.23
SyncMW 10 层 (c=100)135,342.8991,646.87133,061.49
高并发 (c=100)140,643.56149,802.87149,170.97
高并发 (c=1000)65,478.3986,809.8871,551.21
高并发 (c=10000)59,258.9494,281.8962,137.10

高并发 10K Socket Errors: Hical 无错误, Drogon 无错误, Cinatra timeout=919

第三轮(2026-05-25 11:42)

场景HicalDrogonCinatra
Hello World (c=100)138,851.55125,580.99167,866.51
JSON 响应 (c=100)141,122.19110,304.60121,898.13
JSON Echo (c=100)127,830.7163,364.29117,510.76
路径参数 (c=100)140,279.3193,197.92129,945.28
中间件 0 层 (c=100)130,700.88107,628.47138,178.82
中间件 3 层原生 (c=100)140,912.53113,704.01130,484.50
中间件 10 层原生 (c=100)96,007.00109,177.63128,268.96
SyncMW 3 层 (c=100)137,311.12101,405.52137,215.18
SyncMW 10 层 (c=100)142,333.72110,527.95124,236.71
高并发 (c=100)161,013.19161,261.49162,390.92
高并发 (c=1000)61,336.6875,602.2763,918.27
高并发 (c=10000)59,910.86109,031.9058,776.93

高并发 10K Socket Errors: Hical 无错误, Drogon timeout=7, Cinatra timeout=1062


测试日期:2026-05-25 | 宿主机:i7-11700K / 32GB | VM:VirtualBox 7.1 + Ubuntu 24.04 (16GB/8CPU) | 容器:Docker 29.4,4 CPU / 1GB per container,nofile=65536 | 工具:wrk 4.1.0 | 每场景 3 轮取平均值

http://www.rkmt.cn/news/1403112.html

相关文章:

  • 3D EXIT图分析:解码SLDPC迭代收敛与硬件性能权衡
  • Windows 10安卓子系统反向移植:技术实现与部署深度解析
  • 猫抓浏览器扩展:三步轻松掌握网页资源获取的终极方案
  • 2026哪家装修公司收费合理,没有增项和套路 - 大渝测评
  • Pixverse 视频生成 API 集成指南
  • RRAM神经加速器端到端设计:从算法到电路的电路级验证流程
  • 搭 K8s 环境踩过这 4 个坑,你就能少走半个月弯路【系列一】
  • 有限域GF(2^m)渐近平方根算法:原理、推导与硬件实现
  • GEO生成引擎优化:2026年AI搜索时代的流量新变量
  • 高洁净循环泵厂家排名:半导体制药行业优选指南 - 资讯焦点
  • 2026亲测:专业AI智能降重工具选这款就对了3秒改写无痕迹
  • 查看mysql数据库容量大小
  • 认识电子元器件 —— 三极管与MOS管篇:参数、选型与应用
  • 如何完整备份微信聊天记录:WeChatMsg三步实现数据永久保存
  • 从流量入口到容器实例:图解 K8s Service、Endpoints 与 Pod 的联动机制
  • LeetDown:让老款iPhone/iPad重获新生的iOS降级神器
  • 屏蔽泵厂家哪家好?2025年国内屏蔽泵品牌实力对比与选型指南 - 资讯焦点
  • Equalizer APO:颠覆性音频驱动层处理引擎解析
  • 4D标注踩坑实录:从选型到交付的血泪经验
  • Obsidian插件汉化终极指南:快速实现中文界面的完整解决方案
  • GEO实战复盘:从RAG检索机制反推内容优化逻辑(附2026实测数据)
  • 2026年广告行业数码印花设备升级指南:大笨象数码深度解析 - 资讯焦点
  • 3分钟搞定:新手也能轻松完成的Axure全版本中文界面配置终极指南
  • 看看别人的开发速度------5个月120个APP
  • MacBook玩转Git全攻略:从零安装到实战协作一篇通!
  • 3PEAK思瑞浦 TPA5512-DFGR DFN2X2-8 精密运放
  • 如何在5分钟内掌握高效批量打开网址的终极技巧
  • Bun 一周内用 Rust 重写,维护者单方面改动引未来质疑
  • 3步开启数字电路设计之旅:用Digital模拟器打造你的第一个逻辑电路
  • ACL 2026 | 7000种语言怎么教?清华阿里找准语义瓶颈,通关多语言安全