秒杀系统高并发优化实战(C++ / Drogon)· 总路线图(Master Plan)
秒杀系统高并发优化实战(C++ / Drogon)· 总路线图(Master Plan)
目标:用「讲透式」博客(是什么 → 坑在哪 → 本质一句话 → 关键 C++ 代码 / 内联 SVG → 对比表)从 0 到 1 用 C++ 渐进式搭建一个支撑高并发的秒杀系统。
通过问题驱动 + 压测验证,把系统 QPS 从 50 拉到 30000+,清晰看到「单体 → 微服务」的架构演进全过程。
这是作者个人的实战记录:重点不在堆功能,而是每一步的项目思考、实现路径,以及关键功能抉择上的权衡(例如"为什么 Redis 预热而不是直接落库""为什么 Lua 原子扣减而不是分布式锁""为什么异步下单而不是同步落库"),并补上 C++ 特有的系统级拆解(epoll、协程、无锁队列、内存池)。
读法:先骨架后血肉——先把「业务挑战 + 4 阶段架构演进」看明白,再逐阶段下钻到表设计、登录、缓存、MQ、Lua 预扣、防刷限流。
〇、阅读约定(本系列)
- 技术栈(C++ 实现):
- Web 框架:Drogon(C++14/17,基于 epoll 的异步 I/O + 协程,内置 JSON / ORM / Redis 客户端)
- 数据库:MySQL(
mysql-connector-cpp或soci+ 自管理连接池) - 缓存:Redis(
redis-plus-plus封装hiredis;库存预热、Lua 原子脚本) - 消息队列:RabbitMQ(
AMQP-CPP;阶段四内部 RPC 改用brpc) - 鉴权/会话:自实现 Token(
jwt-cpp+ Redis 会话) - 分布式锁 / 限流:自实现(Redis
SET NX+ Lua;令牌桶 / 漏桶算法) - 注册配置(阶段四):
etcd或自写轻量注册 - 压测:JMeter(客户端语言无关);容器:Docker
- 每篇结构:开场钩子 → 「是什么 / 坑在哪 / 本质一句话」递进 → 贴出关键 C++ 代码(Drogon handler / SQL / Redis Lua / AMQP)→ 可运行步骤 → 内联 SVG 时序 / 架构图 → 对比表。
- 每篇必带「功能抉择」小节:不只给方案,更给"为什么选 A 而不是 B、放弃了什么代价"的权衡(这是本系列区别于"功能清单式教程"的主线)。
- 图一律 SVG(不写 ASCII 图)。
- 文章内禁止预测下一篇。
- abbrlink 前缀:
seckcpp+ 4 位序号——seckcpp0000本规划,seckcpp0101~`seckcpp08xx` 各篇。 - 分类 / 系列:
categories: [Seckill, Cpp]、series: [Seckill]。 - 日期策略:从
2026-08-28起,2 篇/周(周一 + 周四)向前排;博客已开future: true。逐篇日期表后续生成_schedule.json。
〇-1、配套代码仓库
- GitHub(public):
https://github.com/Hespethorn/seckill-cpp - 每篇文章对应的可运行代码按阶段提交,版本以
vX.Y.Ztag 标记。阶段一v0.1.0已实现 Drogon 骨架 + 事务化 DB 直扣秒杀(核心逻辑在src/service/SeckillService.cc:原子UPDATE ... WHERE stock>0+ 订单落库包同一事务)。 - 真实编译在本地 WSL(Ubuntu)完成;发布走
scripts/release.sh <版本号>(构建 → 提交 → 打 tag → 推 GitHub)。沙箱环境无编译器,只负责写源码 + git 提交/打 tag/SSH 推送。
一、为什么要做秒杀系统(7 大业务挑战,语言无关)
秒杀是互联网大厂面试高频考点,也是最能体现高并发架构设计能力的实战项目。需逐个攻克:
- 瞬时高并发流量:活动开始请求量达平时几十~上百倍,连接 / 数据库被耗尽。
- 库存超卖:10000 人抢 100 件,如何不多卖。
- 重复下单:同一用户多次秒杀成功,如何防止。
- 黄牛刷单:脚本 / 机器人 / 多账号抢购,如何保公平。
- 服务雪崩:下游订单 / 支付慢导致调用方资源占满,级联故障。
- 数据一致性:Redis 预减 + MQ 异步下单 + DB 最终扣减,如何不丢不一致。
- 系统可扩展性:用户量 / 活动规模增长,如何水平扩展。
本系列视角:以上每个坑都当成一次功能抉择来讲——不只给"怎么解",更给"为什么选它、为此放弃了什么"。例如超卖,乐观锁 / 悲观锁 / SQL 条件判断各有代价,要讲清取舍而非只甩一句"用乐观锁"。
二、架构演进路线(4 阶段:50 QPS → 30000+ QPS,C++ 实现)
1 | 阶段一 基础秒杀系统(Drogon + MySQL 直连) ~50 QPS |
各阶段瓶颈与解法,详见开篇《专栏介绍》的内联 SVG(已标注 C++ 技术栈)。
三、完整目录(8 章 / 约 76 篇,C++ 实现)
一、项目介绍
- 1.1 介绍(项目定位、权衡主线与路线图)——
seckcpp0101
二、表设计与项目搭建
- 2.1 数据库表设计(MySQL)——
seckcpp0201 - 2.2 后端接口梳理与设计(REST 路由规划)——
seckcpp0202 - 2.3 Drogon 多模块项目搭建(CMake + 子项目)——
seckcpp0203 - 2.4 接入 MySQL:mysql-connector-cpp / soci + 自管理连接池 ——
seckcpp0204 - 2.5 完善项目基础设施(配置 / 日志 / 全局异常)——
seckcpp0205 - 2.6 整合高性能异步日志(spdlog + 环形缓冲,替代 Log4j2+Disruptor)——
seckcpp0206
三、登录模块开发(自实现鉴权,无 SaToken)
- 3.1 整合 jwt-cpp + Redis 会话:用户注册接口 ——
seckcpp0301 - 3.2 用户登录接口实现(密码哈希 bcrypt / scrypt)——
seckcpp0302 - 3.3 短信验证码接口:redis-plus-plus + 自实现异步线程池 / 协程 ——
seckcpp0303 - 3.4 注册 / 登录验证码校验 & Token 持久化到 Redis ——
seckcpp0304 - 3.5 验证码安全加固:Redis Lua 原子校验 + 每日发送上限 ——
seckcpp0305 - 3.6 登录安全加固:密码错误次数限制 + 账号临时锁定 ——
seckcpp0306 - 3.7 退出登录接口开发 ——
seckcpp0307 - 3.8 代码细节重构 ——
seckcpp0308 - 3.9 验证码接口安全加固:滑块验证码(自实现或接入行为验证)——
seckcpp0309
四、基础秒杀功能(阶段一:Drogon + MySQL 直连)
- 4.1 秒杀商品列表接口开发 ——
seckcpp0401 - 4.2 秒杀商品详情接口开发 ——
seckcpp0402 - 4.3 秒杀下单接口开发(基础版,同步落库)——
seckcpp0403 - 4.4 JMeter 压测:100 用户抢 10 件,暴露超卖 ——
seckcpp0404 - 4.5 JMeter 压测:暴露重复下单 ——
seckcpp0405 - 4.6 解决超卖:乐观锁 vs 悲观锁 vs SQL 条件判断(MySQL 层)——
seckcpp0406 - 4.7 JMeter 压测:基线性能测试 + 阶段一总结 ——
seckcpp0407 - 4.8 应用层锁(std::mutex / 自旋 / 原子)优化重复下单 ——
seckcpp0408
五、引入缓存层:读性能优化(阶段二,redis-plus-plus)
- 5.1 缓存 Key 设计规范与接口基线压测 ——
seckcpp0501 - 5.2 加 Redis 缓存:商品列表接口 ——
seckcpp0502 - 5.3 加 Redis 缓存:商品详情接口 ——
seckcpp0503 - 5.4 聊聊缓存一致性(Cache-Aside / 延迟双删)——
seckcpp0504 - 5.5 缓存预热与动态 TTL ——
seckcpp0505 - 5.6 防缓存穿透:空值策略 ——
seckcpp0506 - 5.7 防缓存穿透:布隆过滤器前置校验(自实现或
bloom)——seckcpp0507 - 5.8 引入本地缓存(自实现 LRU /
libcache)做多级缓存 ——seckcpp0508
六、消息队列削峰填谷:异步秒杀下单(阶段三,AMQP-CPP)
- 6.1 Docker 安装 RabbitMQ ——
seckcpp0601 - 6.2 AMQP-CPP 接入 RabbitMQ:基础收发测试 ——
seckcpp0602 - 6.3 秒杀异步下单架构设计 ——
seckcpp0603 - 6.4 MQ 异步秒杀下单编码实现 ——
seckcpp0604 - 6.5 异步下单 JMeter 性能压测 ——
seckcpp0605 - 6.6 并发消费 MQ:多消费者线程 / 协程(告别单线程串行)——
seckcpp0606 - 6.7 消费者削峰:prefetch + 并发度配置 ——
seckcpp0607 - 6.8 消费者可靠性:手动 ACK + 死信队列(AMQP-CPP 语义)——
seckcpp0608 - 6.9 生产者可靠性:Confirm + Return 机制 ——
seckcpp0609 - 6.10 秒杀结果查询接口(异步后用户怎么知道抢没抢到)——
seckcpp0610 - 6.11 秒杀结果 SSE / WebSocket 实时通知(Drogon 原生支持)——
seckcpp0611
七、Redis Lua 脚本原子预扣缓存(阶段四上半)
- 7.1 为什么 MQ 削峰之后,MySQL 行锁仍是瓶颈 ——
seckcpp0701 - 7.2 秒杀库存预热到 Redis(redis-plus-plus)——
seckcpp0702 - 7.3 Redis Lua 脚本实现库存原子扣减 ——
seckcpp0703 - 7.4 Redis Lua 脚本实现一人一单限制 ——
seckcpp0704 - 7.5 Redis Lua 接入秒杀下单主链路 ——
seckcpp0705 - 7.6 MQ 发送失败时库存回补(1)——
seckcpp0706 - 7.7 MQ 发送失败时库存回补(2)——
seckcpp0707 - 7.8 Redis 预扣后消费者链路优化 ——
seckcpp0708 - 7.9 库存售罄标记与快速失败 ——
seckcpp0709 - 7.10 秒杀商品查询接口升级:组合 Redis 实时库存 ——
seckcpp0710 - 7.11 JMeter 压测验收本阶段成果 ——
seckcpp0711
八、防刷、限流与秒杀资格校验(阶段四下半,自实现治理)
- 8.1 为什么秒杀系统必须做防刷与限流 ——
seckcpp0801 - 8.2 手写接口限流器:Redis Lua 固定窗口 / 滑动窗口挡高频请求 ——
seckcpp0802 - 8.3 令牌桶 / 漏桶算法自实现 + 中间件解耦 ——
seckcpp0803 - 8.4 秒杀令牌设计:给下单接口加资格校验 ——
seckcpp0804 - 8.5 一次性秒杀令牌:防同一 token 重复提交 ——
seckcpp0805 - 8.6 秒杀令牌大闸:按库存数量控制令牌发放量 ——
seckcpp0806 - 8.7 并发 Bug 修复:重复扣大闸与 token 覆盖 ——
seckcpp0807 - (后续章节持续扩展)
四、分阶段日期表(8 章 / 约 76 篇,2 篇/周向前排)
| 阶段 | 章 | 篇数 | 起始(计划) | 主题 |
|---|---|---|---|---|
| 开篇 | 一 | 1 | 2026-08-28 | 项目介绍 / 架构演进 |
| 地基 | 二 | 6 | 2026-08-31 | 表设计 / Drogon 项目搭建 |
| 登录 | 三 | 9 | 2026-09-21 | 自实现鉴权与会话 |
| 阶段一 | 四 | 8 | 2026-11-02 | Drogon + MySQL 直连版 |
| 阶段二 | 五 | 8 | 2026-12-28 | redis-plus-plus 缓存读优化 |
| 阶段三 | 六 | 11 | 2027-02-22 | AMQP-CPP 削峰填谷 |
| 阶段四上 | 七 | 11 | 2027-05-03 | Lua 原子预扣 |
| 阶段四下 | 八 | 7+ | 2027-07-12 | 自实现防刷 / 限流 / 令牌 |
五、你能学到什么(C++ 能力地图)
- 从 0 到 1 用 C++ 把 QPS 从 50 拉到 30000+;
- Drogon 全栈:异步 I/O、协程、REST 路由、内置 ORM / Redis 客户端;
- MySQL 接入与连接池自管理(HikariCP 思路移植);
- Redis(redis-plus-plus):库存预热、Lua 原子扣减、缓存穿透 / 击穿 / 雪崩三大解法;
- 消息队列(AMQP-CPP):异步下单、削峰填谷、Confirm/Return + 手动 ACK + 死信可靠性;
- 分布式锁 / 限流自实现(Redis
SET NX+ Lua、令牌桶 / 漏桶)—— Java 生态开箱即用,这里全自己写,更见功力; - 系统级拆解:epoll 事件循环、协程切换开销、无锁环形队列、对象池 / 内存池、原子与内存序;
- 页面静态化 + CDN、JWT 鉴权与会话;
- 单体到微服务演进:brpc 内部 RPC、etcd 注册配置、自写网关与熔断;
- Docker 中间件、JMeter 压测逐阶段验收、生产级库存 / 售罄 / 闸门方案。
六、适用人群与技术储备
- 适用人群:有 C++ 基础、想做高并发 / 系统编程实战的开发者;系统岗 / 后端岗面试需要差异化项目加分。
- 技术储备:现代 C++(C++14/17,懂智能指针 / 协程 / 原子更好);用过 Drogon 或愿意学;了解 MySQL / Redis 基础。
七、关于本系列
- 本系列是作者个人用 C++ 从零搭建高并发秒杀系统的实战记录,所有方案、代码、压测数据均为原创。
- 写作主线不是"堆功能清单",而是项目思考 + 实现路径 + 功能抉择的权衡:每个决策都交代"为什么选 A 而不是 B、放弃了什么代价"。
- 若你更熟悉 Java 生态(Spring Boot / Redisson / Sentinel),可把文中的 C++ 自实现组件对照理解为对应中间件的等价物,但本系列不依赖任何外部教程。
All articles on this blog are licensed under CC BY-NC-SA 4.0 unless otherwise stated.

