从零构建现代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

搭建 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

Boost 库学习课程 — 学习路径导航

本系列以 Hical 框架源码为实战案例,系统讲解项目使用的 5 个核心 Boost 库。 本系列与 Hical 框架系列的关系 系列 视角 目标读者 Hical 框架系列(01-05) 框架怎么设计 想理解 Hical 架构的人 Boost 学习课程 Boost 库怎么用 想掌握 Boost 库本身的人 同一段源码(如 TcpServer::acceptLoop()),Blog 讲 “为什么用协程做 accept 循环”,本系列讲 "async_accept + use_awaitable 的 API 语义是什么"。 学习路径 1 2 3 4 5 6 7 8 9 10 11 课程 1: Boost.System ← 最基础,error_code 是所有 I/O 操作的返回值 │ ▼ 课程 2: Boost.Asio ← 核心 I/O 引擎,依赖 error_code │ ├───────────────┐ ▼ ▼ 课程 3: Boost.Beast 课程 5: Boost.MySQL ← 都构建在 Asio 异步模型之上 │ ▼ 课程 4: Boost.JSON ← 数据层,与 HTTP 请求/响应及数据库结果配合 课程概览 # 课程 核心主题 前置依赖 预计时长 1 Boost.System 统一错误码、error_category、跨平台映射 C++ 基础 1-2 小时 2 Boost.Asio io_context、协程、TCP、定时器、多线程模型 课程 1 4-6 小时 3 Boost.Beast HTTP 消息模型、Parser、WebSocket、SSL 课程 1+2 3-4 小时 4 Boost.JSON 值类型体系、解析/序列化、PMR 集成、反射 课程 1 2-3 小时 5 Boost.MySQL 协程式数据库访问、连接池、PreparedStatement 缓存 课程 1+2 3-5 小时 各课程一句话摘要 课程 1 — Boost.System:理解 error_code + error_category 体系,掌握 I/O 操作的两种错误处理模式(错误码 vs 异常)。 课程 2 — Boost.Asio:从 io_context 出发,掌握 C++20 协程式异步 I/O,学会 TCP 服务器、定时器和多线程模型。 课程 3 — Boost.Beast:在 Asio 之上构建 HTTP/WebSocket 协议层,学会请求解析、响应构建和 WebSocket 消息循环。 课程 4 — Boost.JSON:掌握 JSON 值类型操作、PMR 高性能分配,以及 Hical 反射层如何实现自动序列化。 课程 5 — Boost.MySQL:掌握协程式异步数据库访问、参数化查询防注入、连接池设计,以及 Hical 的 Statement 缓存与数据库中间件。 开发环境准备 编译器要求 编译器 推荐版本 GCC 14+ Clang 20+ MSVC 2022 Boost 安装 Linux (apt): ...

April 15, 2026 · 2 min · 259 words

Boost.Asio 学习课程:异步 I/O 与协程

课程导航:学习路径 | Boost.System | Boost.Asio | Boost.Beast | Boost.JSON | Boost.MySQL 前置知识 课程 1: Boost.System(error_code、system_error) C++ 基础:模板、lambda、智能指针 C++20 协程语法(co_await、co_return)——本课程会从零讲解 学习目标 完成本课程后,你将能够: 理解 io_context 的工作原理和生命周期管理 掌握 C++20 协程式异步编程(co_await + use_awaitable) 编写协程式 TCP 服务器和客户端 使用 steady_timer 实现定时任务 理解多线程模型的选型和 strand 序列化 读懂 Hical 的 EventLoop、连接管理和 SSL 集成 目录 前置知识 学习目标 目录 1. 核心概念 1.1 Asio 的设计哲学 1.2 io_context:事件循环的心脏 1.3 Executor 模型:post vs dispatch 1.4 三种异步完成方式 2. 基础用法 2.1 最小 io_context 示例 2.2 TCP 基础:同步与异步 2.3 协程式异步 I/O 2.4 steady_timer 定时器 2.5 buffer 操作 3. 进阶主题 3.1 多线程模型 3.2 strand 序列化执行 3.3 SSL/TLS 支持 3.4 signal_set 信号处理 4. Hical 实战解读 4.1 AsioEventLoop:io_context 的框架封装 4.2 dispatch vs post 实战 4.3 EventLoopPool:多线程池模型 4.4 AsioTimer:定时器的生产级封装 4.5 TcpServer:协程式 accept 循环 4.6 Coroutine.h:协程工具函数 4.7 SSL 集成 5. 练习题 练习 1:协程式 Echo Server 练习 2:周期性日志 练习 3:多 io_context 模型 练习 4:SSL Echo Server 练习 5:协程式 HTTP 客户端 参考答案 练习 1 参考答案:协程式 Echo Server 练习 2 参考答案:周期性日志 练习 3 参考答案:多 io_context 模型 练习 4 参考答案:SSL Echo Server 练习 5 参考答案:协程式 HTTP 客户端 6. 总结与拓展阅读 核心 API 速查表 三种异步模式对比 拓展阅读 下一步 1. 核心概念 1.1 Asio 的设计哲学 Boost.Asio 采用 Proactor 模式——应用程序发起异步操作,操作系统完成后通知应用。 ...

April 15, 2026 · 20 min · 4250 words

Boost.Beast 学习课程:HTTP 与 WebSocket

课程导航:学习路径 | Boost.System | Boost.Asio | Boost.Beast | Boost.JSON | Boost.MySQL 前置知识 课程 1: Boost.System(error_code、system_error) 课程 2: Boost.Asio(io_context、协程、TCP socket) HTTP 协议基础(请求/响应格式、状态码、头部) 学习目标 完成本课程后,你将能够: 理解 Beast 的 HTTP message 模型和 Body 类型系统 使用 Parser 安全解析 HTTP 请求(含 body_limit 保护) 编写协程式 HTTP 服务端和客户端 实现 WebSocket 升级和消息循环 读懂 Hical 的 HttpServer、HttpRequest/Response 封装和 WebSocket 集成 目录 前置知识 学习目标 目录 1. 核心概念 1.1 Beast 的定位 1.2 HTTP message 模型 1.3 Buffer 体系 1.4 Parser 与安全限制 2. 基础用法 2.1 构建 HTTP 请求和响应 2.2 协程式 HTTP 服务端 2.3 Parser 高级用法 3. 进阶主题 3.1 WebSocket 3.2 自定义 Body 类型 3.3 超时机制 4. Hical 实战解读 4.1 handleSession:完整 HTTP 处理循环 4.2 HttpRequest/Response 封装 4.3 WebSocketSession 封装 4.4 handleWebSocket:升级与消息循环 4.5 错误处理模式 5. 练习题 练习 1:基础 HTTP 服务端 练习 2:body_limit 保护 练习 3:WebSocket Echo Server 练习 4:Keep-Alive 练习 5(挑战):静态文件服务器 参考答案 练习 1 参考答案:基础 HTTP 服务端 练习 2 参考答案:body_limit 保护 练习 3 参考答案:WebSocket Echo Server 练习 4 参考答案:Keep-Alive 练习 5 参考答案:静态文件服务器 6. 总结与拓展阅读 Beast 核心 API 速查表 HTTP 请求处理数据流 拓展阅读 下一步 1. 核心概念 1.1 Beast 的定位 Beast 是协议实现库,不是 Web 框架。它在 Asio 之上添加 HTTP/WebSocket 协议的解析和序列化,但不提供路由、中间件等应用层功能(这些由 Hical 提供)。 ...

April 15, 2026 · 19 min · 3882 words

Boost.JSON 学习课程:JSON 序列化与反序列化

课程导航:学习路径 | Boost.System | Boost.Asio | Boost.Beast | Boost.JSON | Boost.MySQL 前置知识 课程 1: Boost.System(error_code 用于安全解析) C++ 基础:模板、if constexpr、可变参数模板 JSON 数据格式基础 学习目标 完成本课程后,你将能够: 掌握 Boost.JSON 的值类型体系(value/object/array) 安全解析和序列化 JSON 数据 理解 PMR 分配器如何加速 JSON 操作 读懂 Hical 的 MetaJson 反射层——自动 JSON 序列化的实现原理 目录 前置知识 学习目标 目录 1. 核心概念 1.1 Boost.JSON vs 其他 JSON 库 1.2 值类型体系 1.3 构造与访问 2. 基础用法 2.1 创建 JSON 值 2.2 解析 JSON 字符串 2.3 序列化为字符串 2.4 访问和修改 2.5 类型转换 3. 进阶主题 3.1 PMR 分配器集成 3.2 增量解析 3.3 tag_invoke 自定义序列化 3.4 错误处理 4. Hical 实战解读 4.1 HttpRequest::jsonBody() 4.2 HttpResponse::setJsonBody() 4.3 HttpResponse::json() 工厂 4.4 MetaJson.h:反射驱动的自动序列化 4.5 PMR 与 JSON 的协同 5. 练习题 练习 1:JSON 解析与提取 练习 2:HICAL_JSON 宏实战 练习 3:安全 JSON 验证器 练习 4:PMR 性能对比 练习 5(挑战):扩展 valueToJson 参考答案 练习 1 参考答案:JSON 解析与提取 练习 2 参考答案:HICAL_JSON 宏实战 练习 3 参考答案:安全 JSON 验证器 练习 4 参考答案:PMR 性能对比 练习 5 参考答案:扩展 valueToJson 支持 optional 6. 总结与拓展阅读 C++ 类型 ↔ JSON 类型映射表 API 速查表 拓展阅读 课程回顾 1. 核心概念 1.1 Boost.JSON vs 其他 JSON 库 特性 Boost.JSON nlohmann::json RapidJSON simdjson 接口风格 Boost 风格 STL 风格 SAX/DOM 只读 PMR 支持 原生 无 自定义 Allocator 无 增量解析 stream_parser 无 SAX API 无 编译速度 快(header-only 可选) 慢 快 快 可变性 读写 读写 读写 只读 Boost 集成 天然 独立 独立 独立 Hical 选择 Boost.JSON 的原因: ...

April 15, 2026 · 18 min · 3645 words

Boost.System 学习课程:错误处理基石

课程导航:学习路径 | Boost.System | Boost.Asio | Boost.Beast | Boost.JSON | Boost.MySQL 前置知识 C++ 基础(类、模板、异常处理) 了解操作系统错误码概念(errno、GetLastError) 学习目标 完成本课程后,你将能够: 理解 error_code + error_category 的设计原理 掌握 I/O 操作中 错误码 和 异常 两种错误处理模式 编写自定义 error_category 读懂 Hical 的跨平台错误码映射层 目录 前置知识 学习目标 目录 1. 核心概念 1.1 为什么需要统一的错误码体系 1.2 error_code 三要素 1.3 error_category 体系 1.4 error_condition vs error_code 2. 基础用法 2.1 创建和检查 error_code 2.2 两种错误处理模式 2.3 常见错误码速查表 3. 进阶主题 3.1 自定义 error_category 3.2 跨平台错误码映射 4. Hical 实战解读 4.1 Error.h:框架级错误码枚举 4.2 Error.cpp:fromBoostError 跨平台映射 4.3 错误码在连接管理中的使用 4.4 设计模式总结 5. 练习题 练习 1:error_code 基础 练习 2:自定义 error_category 练习 3:阅读源码 参考答案 练习 1 参考答案 练习 2 参考答案 练习 3 参考答案 6. 总结与拓展阅读 核心要点 拓展阅读 下一步 1. 核心概念 1.1 为什么需要统一的错误码体系 C 语言 errno 的问题: ...

April 15, 2026 · 12 min · 2361 words

Hical 框架应用场景全景分析

Hical 是一个现代 C++ 高性能 Web 框架,基于 Boost.Asio/Beast,具备 PMR 内存池、协程异步 I/O、WebSocket、SSL/TLS、C++26 反射层等特性。本文覆盖游戏行业 + 通用行业的全部适用场景。 一、游戏行业场景(简要) 场景 说明 GM/运营后台 REST API + 静态页面 + Session 鉴权 支付/SDK 回调网关 高并发 HTTP 接入,协程非阻塞 WebSocket 实时服务 聊天、排行榜推送、GM 监控 内部微服务 HTTP 层 MetaJson/MetaRoutes 零样板代码 二、通用行业场景 1. IoT / 嵌入式设备管理后台 ⭐ 高匹配度 为什么适合: IoT 网关和嵌入式设备普遍用 C/C++ 开发,Hical 保持语言一致性 单二进制部署,无运行时依赖,适合资源受限环境(树莓派、工控机) PMR 内存池提供可预测的内存行为,避免 GC 抖动 WebSocket 双向通信天然适合设备状态实时推送 典型用例: 设备状态监控 Dashboard(HTTP + WebSocket 推送) 固件 OTA 更新接口(Multipart 文件上传) 传感器数据采集 HTTP 接口 边缘计算节点的本地 Web 管理界面 2. 高频交易 / 量化金融辅助服务 为什么适合: ...

April 13, 2026 · 2 min · 359 words