秒杀系统高并发优化实战(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 客户端)
    • 数据库:MySQLmysql-connector-cppsoci + 自管理连接池)
    • 缓存:Redisredis-plus-plus 封装 hiredis;库存预热、Lua 原子脚本)
    • 消息队列:RabbitMQAMQP-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.Z tag 标记。阶段一 v0.1.0 已实现 Drogon 骨架 + 事务化 DB 直扣秒杀(核心逻辑在 src/service/SeckillService.cc:原子 UPDATE ... WHERE stock>0 + 订单落库包同一事务)。
  • 真实编译在本地 WSL(Ubuntu)完成;发布走 scripts/release.sh <版本号>(构建 → 提交 → 打 tag → 推 GitHub)。沙箱环境无编译器,只负责写源码 + git 提交/打 tag/SSH 推送。

一、为什么要做秒杀系统(7 大业务挑战,语言无关)

秒杀是互联网大厂面试高频考点,也是最能体现高并发架构设计能力的实战项目。需逐个攻克:

  1. 瞬时高并发流量:活动开始请求量达平时几十~上百倍,连接 / 数据库被耗尽。
  2. 库存超卖:10000 人抢 100 件,如何不多卖。
  3. 重复下单:同一用户多次秒杀成功,如何防止。
  4. 黄牛刷单:脚本 / 机器人 / 多账号抢购,如何保公平。
  5. 服务雪崩:下游订单 / 支付慢导致调用方资源占满,级联故障。
  6. 数据一致性:Redis 预减 + MQ 异步下单 + DB 最终扣减,如何不丢不一致。
  7. 系统可扩展性:用户量 / 活动规模增长,如何水平扩展。

本系列视角:以上每个坑都当成一次功能抉择来讲——不只给"怎么解",更给"为什么选它、为此放弃了什么"。例如超卖,乐观锁 / 悲观锁 / SQL 条件判断各有代价,要讲清取舍而非只甩一句"用乐观锁"。

二、架构演进路线(4 阶段:50 QPS → 30000+ QPS,C++ 实现)

1
2
3
4
5
6
7
阶段一  基础秒杀系统(Drogon + MySQL 直连)        ~50 QPS
↓ 引入 redis-plus-plus 缓存(读优化 + 库存预热)
阶段二 缓存层 Redis ~数千 QPS
↓ 引入 AMQP-CPP(异步下单 + 削峰填谷)
阶段三 消息队列削峰填谷 ~万级 QPS
↓ 微服务拆分 + 自实现服务治理(brpc / etcd / 令牌桶)
阶段四 微服务 + 服务治理 ~30000+ 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++ 自实现组件对照理解为对应中间件的等价物,但本系列不依赖任何外部教程。