实测:C++20 协程 vs Go Gin vs Rust Actix,谁的 Web 性能更强?

实测:C++ vs Go vs Rust,谁的 Web 性能更强? “2026 年了,还有人用 C++ 写 Web 服务?” 这个问题我被问过不止一次。答案是:有,而且有相当充分的理由。本文不是要说服你用 C++,而是把三种语言放在同一个擂台上,用数据说话,帮你在实际项目里做出最合适的选择。 目录 1. 背景:三种语言在 Web 领域的 2026 年现状 2. 测试环境与方法论 3. Hello World QPS 对比 4. JSON CRUD QPS 对比 5. 内存占用对比 6. 开发效率对比 7. 生态与工具链对比 8. 各语言适用场景 9. 总结 1. 背景:三种语言在 Web 领域的 2026 年现状 C++:从游戏服务器到高性能 API C++ 在 Web 领域长期处于"少数派"地位,但 2020 年代之后情况在变化。C++20 协程(co_await)和 PMR 内存池让 C++ 的异步 Web 编程体验大幅改善;C++26 的反射提案进一步压缩了模板样板代码。游戏公司、金融公司、CDN 基础设施商是 C++ Web 服务的主要用户群——他们要么已经有大量 C++ 代码,要么对延迟的要求超出了 GC 语言的舒适区。 ...

May 2, 2026 · 11 min · 2231 words

游戏服务器的 HTTP API 层:为什么我们选择 C++ 而非 Go

游戏服务器的 HTTP API 层:为什么我们选择 C++ 而非 Go 游戏服务器迟早要暴露 HTTP API,问题不是"要不要",而是怎么加。单独起一个 Go/Python sidecar?还是直接嵌进 C++ 进程?十年以上游戏服务器开发经验告诉我——后者往往是更务实的选择。本文结合 Hical 框架的实践,聊聊背后的取舍。 游戏服务器需要 HTTP API 吗? 很多人的第一反应是"游戏用的是自定义 TCP 协议,要 HTTP 干嘛"。但在实际运营中,HTTP API 的需求无处不在: 运营 GM 工具:封号、解封、发补偿道具、改玩家数据。运营人员不会连服务器敲命令,他们需要一个 Web 界面,背后是 HTTP API。 充值回调:支付平台(微信支付、支付宝、Apple IAP)在用户付款成功后,会用 HTTP POST 通知你的服务器,这个通知必须落到游戏服务器上,否则如何给玩家加钻石? 公告系统:运营在 CMS 后台写好公告,需要一个接口通知游戏服务器"有新公告了,推给在线玩家"。 排行榜 / 战报分享:玩家把战报链接发给朋友,朋友点开是个 H5 页面,数据从游戏服务器的 HTTP 接口来。 健康检查:K8s 的 readinessProbe、运维监控系统(Prometheus、Zabbix)都期望一个 GET /health 端点,返回 200 就代表进程活着。 这些场景加在一起,游戏服务器没有 HTTP API 几乎无法正常运营。 为什么不单独起一个 Go 服务? “那我单独用 Go 写个 HTTP 服务不行吗?” 行,但会带来一系列麻烦。 ...

May 2, 2026 · 6 min · 1179 words

从零构建现代C++ Web服务器(七):生产级日志系统

从零构建现代C++ Web服务器(七):生产级日志系统 系列导航:第一篇:设计理念 | 第二篇:协程与内存池 | 第三篇:路由与中间件 | 第四篇:实战与调优 | 第五篇:Cookie 与 Session | 第六篇:数据库中间件 | 第七篇:日志系统(本篇) 前置知识 阅读过第三篇的中间件洋葱模型 了解 C++20 std::format、std::jthread 了解日志系统的基本概念(级别、格式化、输出目标) 目录 1. 为什么需要自研日志系统? 2. Phase 1:基础增强——从 fprintf 到 std::format 3. Phase 2:异步后端——从同步到生产级 4. Phase 3:结构化日志与可观测性 5. 性能深度分析 6. 线程安全设计 7. 实战:5 分钟搭建完整日志体系 8. 总结与设计决策表 9. 核心要点 10. 知识图谱 1. 为什么需要自研日志系统? 前六篇把 hical 的核心骨架搭完了:协程 I/O、内存池、路由、中间件、SSL、会话、数据库。唯一的短板是日志——每次排查问题只能翻 stderr,没有文件、没有结构、没有追踪 ID。真正的生产环境里,日志比功能代码重要得多:功能代码决定程序的行为,日志决定你能不能在凌晨三点用最短时间还原那行让服务崩掉的数据路径。 1.1 现有轮子的取舍 先看市面上的主流方案: 库 优点 对 hical 的问题 spdlog 成熟、快(每秒数百万条)、格式丰富 外部依赖;fmt 与 std::format 语义略有差异 glog Google 出品,稳定 C++03 风格 API;宏冗余;不支持 std::format Trantor drogon 自带,协程时代设计 与 drogon 强耦合,无法独立引入 log4cxx 功能完备、配置文件驱动 重量级;Java 移植风格与现代 C++ 格格不入 自研 零依赖、API 与框架深度融合 需要投入设计成本 hical 的核心约束是零外部依赖——整个框架只依赖 Boost 和 OpenSSL,任何新模块都不能打破这条线。spdlog 引入 fmt 库就已经违规,glog 的 API 风格与现代 C++ 割裂,Trantor 无法解耦。 ...

May 1, 2026 · 25 min · 5197 words

告别手写 API 文档:Hical OpenAPI 自动生成 + Swagger UI 一键集成

告别手写 API 文档:Hical OpenAPI 自动生成 + Swagger UI 一键集成 你是否经历过这种情况:花了半天写好 Swagger 注解,一个需求变更,参数名改了,文档却忘了同步——测试组拿着旧文档联调,来回扯皮两小时? API 文档和代码永远对不上,是后端开发者的经典痛点。本文介绍如何用 Hical 框架的 OpenAPI 模块,让文档从代码中自动生成,彻底消灭这个问题。 一、背景:OpenAPI 3.0 是什么 OpenAPI 3.0(即过去的 Swagger 规范)是描述 HTTP API 的行业标准 JSON/YAML 格式。有了它: Swagger UI / Redoc 可以直接渲染成可交互的文档页面 前端可以一键生成 TypeScript 类型定义 QA 可以直接在浏览器里填参数发请求 手写 OpenAPI YAML 很繁琐,维护成本高。Hical 的方案是:从 C++ 类型系统直接推导出 schema,标注一次,文档自动生成。 二、三步集成概览 1 2 3 步骤 1 定义 DTO,加 HICAL_JSON + HICAL_SCHEMA_NAME 步骤 2 标注路由,加 HICAL_API + builder::* 步骤 3 main() 中 registerRoutesWithOpenApi + serveOpenApi 不需要任何新依赖,OpenAPI 模块默认随 Hical 一起编译(HICAL_WITH_OPENAPI=ON 是默认值),底层复用已有的 Boost.JSON。 ...

May 1, 2026 · 5 min · 1023 words

用 Hical + MySQL 5 分钟搭建 CRUD API(C++20 协程版)

用 Hical + MySQL 5 分钟搭建 CRUD API(C++20 协程版) C++ 访问数据库难吗?2026 年不再难了。本文用 Hical 的协程 DB 中间件,带你从零搭建一个完整的 MySQL CRUD API —— 连接池管理、事务自动提交/回滚、慢查询检测,全部开箱即用,代码比大多数 Python 教程还简洁。 三种姿势对比 方式 代码量 连接池 异步 防注入 裸 mysql_query 多,手动管理连接 手写 阻塞 手拼字符串,危险 ORM(如 ODB) 少,但有运行时膨胀 内置 视实现而定 安全 Hical 协程中间件 少,原生协程 内置 非阻塞 co_await PreparedStatement Hical 走第三条路:连接池是协程化的,查询全部走 PreparedStatement 防注入,事务在中间件层自动管理,业务代码只关心 SQL 逻辑。 环境准备 构建启用数据库支持 1 2 3 4 5 6 7 8 9 10 11 12 # Linux / macOS cmake -B build -DHICAL_WITH_DATABASE=ON -DCMAKE_BUILD_TYPE=Release cmake --build build -j$(nproc) # Windows (MSYS2 MINGW64) cmake -B build -G Ninja -DHICAL_WITH_DATABASE=ON -DCMAKE_BUILD_TYPE=Release cmake --build build # Windows (MSVC + vcpkg) cmake -B build -DHICAL_WITH_DATABASE=ON -DCMAKE_BUILD_TYPE=Release \ -DCMAKE_TOOLCHAIN_FILE=C:/vcpkg/scripts/buildsystems/vcpkg.cmake cmake --build build --config Release 依赖说明 Boost >= 1.85(DB 中间件需要 Boost.MySQL,1.85 版引入 any_connection) OpenSSL(MySQL TLS 连接可选,已是框架强依赖) CMakeLists 里加一行即可: 1 2 target_link_libraries(my_app PRIVATE hical::hical_core) # HICAL_WITH_DATABASE=ON 时 hical_core 自动链接 Boost.MySQL 建表 SQL 1 2 3 4 5 6 7 8 9 10 11 CREATE DATABASE IF NOT EXISTS demo CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; USE demo; CREATE TABLE IF NOT EXISTS users ( id INT UNSIGNED NOT NULL AUTO_INCREMENT, name VARCHAR(64) NOT NULL, email VARCHAR(128) NOT NULL UNIQUE, created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (id) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; 完整 main.cpp 约 80 行,包含连接池初始化、中间件注册、4 个 CRUD 路由: ...

May 1, 2026 · 6 min · 1072 words

从零构建现代C++ Web服务器(六):数据库中间件与协程连接池

从零构建现代C++ Web服务器(六):数据库中间件与协程连接池 系列导航:第一篇:设计理念 | 第二篇:协程与内存池 | 第三篇:路由、中间件与SSL | 第四篇:实战与性能 | 第五篇:Cookie、Session与文件服务 | 第六篇:数据库中间件(本文) 前置知识 阅读过本系列前五篇(特别是第二篇的协程基础和第三篇的中间件洋葱模型) 了解 SQL 基础和 MySQL 数据库操作 了解连接池的基本概念 目录 1. Web 框架为什么需要数据库层 2. 架构总览:六层洋葱 3. 后端抽象:DbConnection 接口 4. MySQL 实现:any_connection 封装 5. LRU PreparedStatement 缓存 6. 协程连接池:用 steady_timer 做信号量 7. DB 中间件:请求级连接生命周期 8. 查询日志:装饰器模式的妙用 9. 综合实战:用户管理 API + 数据库 10. 总结 1. Web 框架为什么需要数据库层 前五篇构建了 hical 的完整 HTTP 骨架——协程驱动的异步 I/O、PMR 内存池、路由、中间件、SSL、Cookie/Session、静态文件。但现实中的 Web 服务几乎都绑定数据库:用户注册要写库、商品查询要读库、交易扣款要事务。 如果把数据库操作留给业务代码自行处理,会出现几个典型问题: 问题 后果 每个请求都新建连接 MySQL 握手 + 认证 ≈ 1-3ms,高并发下成为瓶颈 业务代码管理连接生命周期 忘记关闭 → 连接泄漏,异常时忘记回滚 → 数据不一致 手动拼接 SQL SQL 注入漏洞(游戏服务器的经济系统被注入 = 灾难) 同步 MySQL 客户端 mysql_query() 阻塞 io_context 线程 → 吞吐暴跌 hical v2.3.0 补齐了这最后一块拼图: ...

April 30, 2026 · 20 min · 4080 words

设计 Hical OpenAPI 模块的心得

设计 Hical OpenAPI 模块的心得 一、为什么要做这件事 Hical 框架从一开始就内建了两套反射基础设施:MetaJson(DTO 字段反射)和 MetaRoutes(路由反射)。这意味着框架在编译期就已经知道"每个结构体有哪些字段、叫什么名字、什么类型、是否必填"以及"每个 Handler 有哪些路由、什么方法、什么路径"。 这些信息恰好是生成 OpenAPI spec 所需要的全部输入。 在 C++ Web 框架领域,Drogon 通过插件支持 Swagger,Oat++ 有内建的 API 文档生成,但没有任何 C++ 框架能做到"从 C++20 宏反射层自动导出 OpenAPI 3.0 spec"这件事。这是 Hical 反射层设计的一个天然延伸,也是最有潜力的差异化卖点。 做之前我最担心的问题是:C++20 的宏回退路径能不能提取足够的类型信息来生成 JSON Schema?C++26 的 jsonSchema<T>() 可以用 std::meta::type_of(member) 直接获取字段类型,但 C++20 只有 FieldDescriptor<Class, FieldType> 的成员指针。后来发现,通过 decltype(std::declval<T>().*(field.pointer)) 在 fold expression 的每次展开中推导出具体的 FieldType,完全可以做到。这个验证结果让我决定动手。 二、架构决策 四层分离 最终的架构是四层设计: 1 2 3 4 Layer 4: OpenApiEndpoint.h — serveOpenApi() / Swagger UI Layer 3: OpenApiDocument.h/cpp — 文档组装 Layer 2: OpenApiRegistry.h/cpp — 路由元数据收集 + 标注宏 Layer 1: OpenApiSchema.h — JSON Schema 生成 这不是一开始就想好的。最初的想法是把所有东西塞进一个 OpenApi.h 里——Schema 生成、路由收集、文档组装、端点注册全放一起。但很快发现几个问题: ...

April 30, 2026 · 3 min · 533 words

Boost.MySQL 学习课程:异步数据库访问

课程导航:学习路径 | Boost.System | Boost.Asio | Boost.Beast | Boost.JSON | Boost.MySQL 前置知识 课程 1: Boost.System(error_code、system_error) 课程 2: Boost.Asio(io_context、协程、co_await + use_awaitable) SQL 基础(SELECT/INSERT/UPDATE/DELETE、事务) MySQL 数据库基本操作 学习目标 完成本课程后,你将能够: 理解 Boost.MySQL 的类型擦除连接模型(any_connection) 使用 C++20 协程执行异步数据库操作 掌握参数化查询和 PreparedStatement 防 SQL 注入 理解结果集类型体系(results / static_results) 实现事务控制(BEGIN/COMMIT/ROLLBACK) 读懂 Hical 的连接池、Statement 缓存和数据库中间件设计 目录 前置知识 学习目标 目录 1. 核心概念 1.1 Boost.MySQL 的定位 1.2 连接类型体系 1.3 查询执行模型 1.4 结果集类型体系 2. 基础用法 2.1 建立连接 2.2 执行文本查询 2.3 参数化查询(客户端格式化) 2.4 PreparedStatement 2.5 结果集遍历 2.6 事务控制 3. 进阶主题 3.1 类型擦除连接 any_connection 3.2 静态类型结果集 static_results 3.3 多结果集(存储过程) 3.4 连接池 connection_pool 3.5 错误处理与诊断 4. Hical 实战解读 4.1 MysqlConnection:any_connection 的框架封装 4.2 StmtCache:LRU PreparedStatement 缓存 4.3 DbConnectionPool:协程式连接池 4.4 DbMiddleware:请求级连接生命周期 4.5 DbQueryLog:查询日志装饰器 4.6 完整请求处理流程 5. 练习题 练习 1:协程式 CRUD 练习 2:参数化查询实战 练习 3:事务与错误处理 练习 4:LRU 缓存设计 练习 5(挑战):连接池实现 6. 总结与拓展阅读 核心 API 速查表 查询方式对比 拓展阅读 课程回顾 1. 核心概念 1.1 Boost.MySQL 的定位 Boost.MySQL 是一个纯异步的 MySQL 客户端库,直接实现 MySQL 客户端/服务器协议(不依赖 libmysqlclient),天然集成 Boost.Asio 的异步模型。 ...

April 29, 2026 · 38 min · 7911 words

OpenSSL RAND_bytes 完整原理:从硬件熵到密码学安全随机数

OpenSSL RAND_bytes 完整原理 从操作系统的硬件中断到你代码里的 16 字节 Session ID,随机数经历了什么? 一、为什么需要密码学安全随机数 1.1 一个真实的安全问题 Hical 框架 v1.0.0 的 Session ID 生成: 1 2 3 4 5 6 // v1.0.0(已修复) thread_local std::mt19937_64 rng(std::random_device{}()); std::uniform_int_distribution<uint64_t> dist; uint64_t hi = dist(rng); uint64_t lo = dist(rng); // 拼成 128 位十六进制 Session ID 看起来安全?不安全。 mt19937_64 是梅森旋转算法,一个确定性伪随机数生成器。攻击者只需收集 312 个连续的 64 位输出(约 156 个 Session ID),就能完全重建内部状态,预测此后所有 Session ID。 v2.0.0 的修复: 1 2 3 // v2.0.0 unsigned char buf[16]; RAND_bytes(buf, sizeof(buf)); // OpenSSL 密码学安全随机数 RAND_bytes 基于 AES-256 加密算法,即使攻击者收集到数十亿个输出,也无法预测下一个。 1.2 伪随机 vs 密码学安全随机 维度 伪随机(PRNG) 密码学安全(CSPRNG) 代表 mt19937、rand()、线性同余 RAND_bytes、getrandom(2) 内部状态 可从输出反推 不可从输出反推 前向安全 无(知道当前状态可反推历史) 有(每次输出后更新状态,旧状态不可恢复) 适用场景 模拟、游戏随机、统计抽样 密钥、Session ID、Token、Nonce 性能 ~3ns/64bit ~15ns/16bytes 标准 无 NIST SP 800-90A 判断标准:如果输出泄露后会造成安全影响(Session 劫持、密钥泄露),就必须用 CSPRNG。 ...

April 22, 2026 · 9 min · 1845 words

搭建 Hical HTTP 服务器 — 多平台环境搭建指南

搭建 Hical HTTP 服务器 — 多平台环境搭建指南 概述 本文档涵盖 Hical v2.0.0 在所有支持平台上的环境搭建,包括三种安装方式(vcpkg / Conan / 源码编译)和五个平台(Windows MSYS2、Windows MSVC、Ubuntu/Debian、Fedora/Arch、macOS)。 依赖要求 组件 版本要求 用途 C++ 编译器 GCC 14+ / Clang 22+ / MSVC 2022+ C++20 协程 + C++26 反射(可选) CMake >= 3.20 构建系统 Boost >= 1.70 Asio / Beast / JSON / System OpenSSL 必需 SSL/TLS 支持 Google Test 必需 单元测试 安装方式一:vcpkg(推荐) vcpkg 是最简单的安装方式,一行命令自动解决所有依赖。 安装 vcpkg(如未安装) 1 2 3 git clone https://github.com/microsoft/vcpkg.git cd vcpkg && bootstrap-vcpkg.bat # Windows cd vcpkg && ./bootstrap-vcpkg.sh # Linux / macOS 将 vcpkg 目录加入 PATH,或记住安装路径用于后续 CMAKE_TOOLCHAIN_FILE。 ...

April 22, 2026 · 5 min · 1018 words