C++17 高并发 epoll 电商后端 + 轻量级 SPA 前端
极物电商系统 是一个从零实现的高性能电商平台后端,附带完整的单页应用前端。使用 C++17 手写 epoll 异步 HTTP 服务器、自研线程池、MySQL 连接池和 Redis RESP 协议客户端,不依赖任何第三方 Web 框架。
适合场景:
- 🎓 毕业设计 / 课程项目 — 完整的电商业务闭环
- 📖 C++ 网络编程学习 — epoll ET 模式、HTTP 解析、线程池设计
- 🔧 自建电商原型 — 轻量级、可二次开发
┌─────────────────────────────────────────┐
│ 浏览器 (SPA 前端) │
│ 原生 HTML5 + CSS3 + JavaScript (ES6) │
└──────────────┬──────────────────────────┘
│ HTTP / JSON
┌──────────────▼──────────────────────────┐
│ EpollServer (epoll ET 模型) │
│ ┌─ 路由分发 ─ 匹配 METHOD:/path │
│ └─ 任务投递 → 自研线程池 │
├──────────────────────────────────────────┤
│ 线程池 (动态扩缩容) │
│ ┌─ 优先级队列 (LOW/MED/HIGH/CRITICAL) │
│ ├─ 任务超时取消 / 按 ID 取消 │
│ └─ 性能计数器统计 │
├──────────────────────────────────────────┤
│ Handler 业务层 (20+ handlers) │
│ ┌─ MySQL 连接池 (ConnectionGuard RAII) │
│ └─ Redis 客户端 (RESP 协议原生实现) │
├──────────────────────────────────────────┤
│ MySQL 8.0 ─────── Redis 7 │
│ (持久化存储) (热点缓存/秒杀) │
└──────────────────────────────────────────┘
| 组件 |
文件 |
说明 |
| EpollServer |
src/server/epoll_server.h |
epoll 边缘触发 (ET) + 非阻塞 I/O,epoll_wait 超时 1000ms,每事件 64 个 |
| HTTP Parser |
src/server/http_parser.h |
手写 HTTP/1.1 解析器,支持 URL 解码、form-data 解析、查询参数提取 |
| 线程池 |
src/threadpool/ |
自研通用线程池:优先级队列、动态扩缩容、任务超时/取消、性能指标 |
| MySQL 连接池 |
src/db/connection_pool.h |
线程安全单例,默认 50 连接,ConnectionGuard RAII 自动回收,自动重连 |
| Redis 客户端 |
src/redis/redis_client.h |
零依赖手写 RESP 协议实现,单例,跨平台 socket(WinSock2 / POSIX),自动重连 |
| JSON 构建器 |
src/utils/json_utils.h |
轻量 JSON 序列化,无第三方依赖 |
| 前端 SPA |
frontend/ |
原生 HTML5 + CSS3 + JS,响应式设计,无框架依赖 |
- 主线程:
epoll_wait 循环,仅负责 accept 新连接和读事件检测
- 工作线程池:收到完整请求后通过
pool_.enqueue() 投递,避免在事件循环中阻塞
- MySQL 连接池:每个 handler 从池中借出连接(RAII 自动归还),无需等待数据库连接创建
| 模块 |
功能 |
API |
| 注册登录 |
用户名密码注册、登录、Token 鉴权、退出 |
POST /api/user/register POST /api/user/login POST /api/user/logout |
| 商品浏览 |
分类导航、关键字搜索、轮播推荐、热销排行 |
GET /api/products GET /api/categories GET /api/products/top |
| 搜索 |
搜索历史、热门搜索 |
POST /api/search/save GET /api/search/hot |
| 购物车 |
添加/删除/修改数量/全选 |
POST /api/cart/add GET /api/cart POST /api/cart/update |
| 下单支付 |
创建订单、模拟支付宝支付、订单取消 |
POST /api/order/create POST /api/alipay/pay |
| 物流追踪 |
物流时间线展示、订单级/物流级回退 |
GET /api/order/logistics GET /api/order/detail |
| 评价系统 |
带图评价、查看评价统计 |
POST /api/review/add GET /api/reviews GET /api/review/stat |
| 收藏夹 |
添加/取消收藏、收藏列表 |
POST /api/favorite/add GET /api/favorites |
| 收货地址 |
多地址 CRUD、默认地址 |
POST /api/address/add POST /api/address/default |
| 积分等级 |
积分记录、会员等级、积分兑换优惠券 |
GET /api/user/points POST /api/points/exchange-coupon |
| 浏览历史 |
自动记录、历史查看 |
POST /api/browse/save GET /api/browse/history |
| 通知 |
系统通知、标记已读 |
GET /api/notifications POST /api/notification/read |
基于 Redis 预扣库存 + 信号量限流的高并发秒杀方案:
- 活动管理:商家创建秒杀活动,设置时间段、库存、价格
- 库存预扣:Redis
DECRBY 原子操作预扣库存,避免 MySQL 行锁争用
- 请求限流:
sem_t 信号量控制并发请求量,超载请求直接拒绝
- 异步落单:秒杀请求入内存队列,工作线程批量处理订单写入
- 支付窗口:秒杀成功后限时支付(未支付自动释放库存到 Redis)
| 接口 |
说明 |
GET /api/seckill/activities |
获取秒杀活动列表 |
GET /api/seckill/detail |
秒杀活动详情 |
POST /api/seckill/do |
执行秒杀(核心接口) |
POST /api/seckill/pay |
秒杀订单支付 |
GET /api/seckill/orders |
用户秒杀订单列表 |
| 模块 |
功能 |
| 入驻管理 |
商家入驻申请 + 后台审核 |
| 商品管理 |
商品 CRUD、规格/SKU 管理、上下架 |
| 订单处理 |
发货、退款审核、售后处理 |
| 评价回复 |
回复买家评价 |
| 员工管理 |
多店员权限管理(添加/移除/角色切换) |
| 秒杀管理 |
创建/关闭秒杀活动 |
| 数据统计 |
销售额、订单量趋势 |
| 模块 |
功能 |
| 数据看板 |
全站统计:用户数、订单数、销售额、商户数 |
| 用户管理 |
用户列表、状态修改 |
| 类目管理 |
商品分类 CRUD |
| 商品审核 |
商品状态审核(上架/下架) |
| 商户管理 |
入驻审核、商户状态封禁/解封 |
| 订单管理 |
全站订单查看 |
| 优惠券管理 |
创建/发放优惠券 |
| 退款/售后 |
售后单处理仲裁 |
点击展开完整 API 列表(90+ 接口)
| 方法 |
路径 |
说明 |
| POST |
/api/user/register |
用户注册(SHA256 密码加密) |
| POST |
/api/user/login |
用户登录(返回 Token) |
| GET |
/api/user/info |
获取用户信息 |
| POST |
/api/user/update |
修改用户资料 |
| POST |
/api/user/password |
修改密码 |
| POST |
/api/user/logout |
退出登录(清除 Token) |
| GET |
/api/user/points |
获取用户积分 |
| GET |
/api/user/levels |
获取会员等级信息 |
| POST |
/api/points/exchange-coupon |
积分兑换优惠券 |
| 方法 |
路径 |
说明 |
| GET |
/api/products |
商品列表(分页、分类筛选、关键字搜索) |
| GET |
/api/product/detail |
商品详情(含 Redis 缓存) |
| GET |
/api/product/related |
关联商品推荐 |
| GET |
/api/products/top |
热销/推荐商品 |
| GET |
/api/categories |
商品分类列表 |
| GET |
/api/product/sku |
商品 SKU/规格 |
| POST |
/api/browse/save |
记录浏览历史 |
| GET |
/api/browse/history |
浏览历史列表 |
| POST |
/api/search/save |
保存搜索记录 |
| GET |
/api/search/history |
搜索历史 |
| GET |
/api/search/hot |
热门搜索词 |
| POST |
/api/search/clear |
清空搜索历史 |
| 方法 |
路径 |
说明 |
| POST |
/api/cart/add |
添加商品到购物车 |
| GET |
/api/cart |
获取购物车列表 |
| POST |
/api/cart/update |
修改购物车商品数量 |
| POST |
/api/cart/delete |
删除购物车商品 |
| 方法 |
路径 |
说明 |
| POST |
/api/favorite/add |
收藏商品 |
| POST |
/api/favorite/remove |
取消收藏 |
| GET |
/api/favorites |
收藏列表 |
| GET |
/api/favorite/check |
检查是否已收藏 |
| 方法 |
路径 |
说明 |
| POST |
/api/order/create |
创建订单 |
| POST |
/api/order/pay |
支付订单(模拟支付) |
| POST |
/api/order/cancel |
取消订单 |
| POST |
/api/order/confirm |
确认订单 |
| POST |
/api/order/receive |
确认收货 |
| GET |
/api/order/logistics |
物流信息 |
| GET |
/api/order/detail |
订单详情 |
| GET |
/api/orders |
订单列表 |
| POST |
/api/order/delete |
删除订单(软删除) |
| GET/POST |
/api/order/auto-cancel-expired |
自动取消超时未支付订单 |
| 方法 |
路径 |
说明 |
| GET |
/api/seckill/activities |
秒杀活动列表 |
| GET |
/api/seckill/detail |
秒杀活动详情 |
| POST |
/api/seckill/do |
执行秒杀(Redis 预扣库存) |
| POST |
/api/seckill/pay |
秒杀订单支付 |
| GET |
/api/seckill/orders |
秒杀订单列表 |
| 方法 |
路径 |
说明 |
| POST |
/api/merchant/login |
商户登录 |
| GET |
/api/merchants |
商户列表 |
| GET |
/api/merchant/detail |
商户详情 |
| POST |
/api/merchant/apply |
申请成为商户 |
| GET |
/api/merchant/check |
检查商户状态 |
| POST |
/api/merchant/update |
修改商户信息 |
| POST |
/api/merchant/product/add |
添加商品 |
| POST |
/api/merchant/product/update |
修改商品 |
| POST |
/api/merchant/product/delete |
删除商品 |
| GET |
/api/merchant/products |
商户商品列表 |
| GET |
/api/merchant/orders |
商户订单列表 |
| POST |
/api/merchant/ship |
订单发货 |
| GET |
/api/merchant/reviews |
商品评价列表 |
| POST |
/api/merchant/review/reply |
回复评价 |
| GET |
/api/merchant/statistics |
商户数据统计 |
| GET |
/api/merchant/seckill/orders |
商户秒杀订单 |
| POST |
/api/merchant/seckill/create |
创建秒杀活动 |
| POST |
/api/merchant/seckill/close |
关闭秒杀活动 |
| GET |
/api/merchant/staff |
员工列表 |
| POST |
/api/merchant/staff/add |
添加员工 |
| POST |
/api/merchant/staff/remove |
移除员工 |
| POST |
/api/merchant/staff/role |
修改员工角色 |
| 方法 |
路径 |
说明 |
| GET |
/api/admin/dashboard |
管理看板数据 |
| GET |
/api/admin/statistics |
全站统计 |
| GET |
/api/admin/products |
所有商品列表 |
| POST |
/api/admin/product/status |
修改商品状态 |
| GET |
/api/admin/orders |
所有订单 |
| POST |
/api/admin/user/update |
修改用户信息 |
| GET |
/api/admin/merchant/applies |
商户入驻申请列表 |
| POST |
/api/admin/merchant/approve |
审核商户入驻 |
| POST |
/api/admin/merchant/status |
封禁/解封商户 |
| POST |
/api/admin/category/add |
添加分类 |
| POST |
/api/admin/category/update |
修改分类 |
| POST |
/api/admin/category/delete |
删除分类 |
| POST |
/api/admin/coupon/create |
创建优惠券 |
| 方法 |
路径 |
说明 |
| POST |
/api/refund/apply |
申请退款(旧) |
| GET |
/api/refunds |
退款列表 |
| POST |
/api/after-sale/apply |
申请售后(新,建议使用) |
| GET |
/api/after-sales |
售后列表 |
| GET |
/api/after-sale/detail |
售后详情 |
| POST |
/api/after-sale/return |
退货 |
| POST |
/api/after-sale/cancel |
取消售后申请 |
| 方法 |
路径 |
说明 |
| POST |
/api/address/add |
添加收货地址 |
| POST |
/api/address/update |
修改地址 |
| POST |
/api/address/delete |
删除地址 |
| POST |
/api/address/default |
设置默认地址 |
| GET |
/api/addresses |
地址列表 |
| POST |
/api/review/add |
添加评价 |
| GET |
/api/reviews |
评价列表 |
| GET |
/api/review/stat |
评价统计 |
| GET |
/api/notifications |
通知列表 |
| POST |
/api/notification/read |
标记通知已读 |
| 方法 |
路径 |
说明 |
| GET |
/api/coupons |
可领取优惠券列表 |
| POST |
/api/coupon/receive |
领取优惠券 |
| POST |
/api/coupon/use |
使用优惠券 |
| 方法 |
路径 |
说明 |
| POST |
/api/alipay/pay |
支付宝支付(沙箱模拟) |
| GET |
/api/alipay/return |
支付同步回跳 |
| POST |
/api/alipay/notify |
支付异步通知 |
| GET |
/api/alipay/query |
支付状态查询 |
系统包含 20+ 张表,涵盖电商核心领域:
数据库 ER 图(DBML 格式)位于仓库中:
| 表名 |
说明 |
user |
用户:id、username、password(SHA256)、nickname、role、avatar、points、level、token |
address |
收货地址:关联 user、收件人、电话、省市区、详细地址、默认标志 |
merchant |
商户信息:店铺名、logo、描述、状态(审核中/通过/封禁) |
merchant_user |
商户-用户关联:关联 user 和 merchant、角色(owner/staff) |
merchant_apply |
入驻申请:申请人信息、申请状态 |
| 表名 |
说明 |
category |
商品分类:分类名、父分类 ID、排序 |
product |
商品:关联分类和商户、名称、描述、价格、库存、状态、图片、销量 |
product_image |
商品图片:关联商品、图片 URL、排序 |
sku |
商品 SKU:规格组合、价格、库存 |
| 表名 |
说明 |
cart |
购物车:关联 user 和 product、数量 |
orders |
订单:关联 user 和 merchant、总价、状态、支付方式、物流信息 |
order_item |
订单项:关联订单和商品、数量、单价 |
payment |
支付记录:关联订单、支付方式、金额、状态(pending/success/failed) |
logistics |
物流信息:关联订单、物流单号、物流商、物流状态、时间线 |
| 表名 |
说明 |
coupon |
优惠券:类型(满减/折扣)、门槛、面值、有效期、发放数量 |
user_coupon |
用户优惠券:关联 user 和 coupon、使用状态 |
seckill_activity |
秒杀活动:关联商品、开始/结束时间、秒杀价、总库存 |
seckill_item |
秒杀订单项:关联 seckill_activity 和 user、状态 |
| 表名 |
说明 |
review |
评价:关联订单和商品、评分、内容、图片、商家回复 |
favorite |
收藏:关联 user 和 product |
after_sale |
售后:关联订单、类型(退货/换货/退款)、原因、状态 |
notification |
通知:关联 user、内容、类型、已读状态 |
browse_history |
浏览历史:关联 user 和商品、浏览时间 |
ecommerce-server/
│
├── frontend/ # 前端 SPA
│ ├── index.html # 入口页面(211 行)
│ ├── style.css # 样式表(深色主题,响应式)
│ └── app.js # 应用逻辑(3528 行,全部前端功能)
│
├── src/ # C++ 后端源码
│ ├── main.cpp # 入口:初始化、路由注册、启动服务器
│ │
│ ├── server/ # HTTP 服务器
│ │ ├── epoll_server.h # epoll 边缘触发事件循环
│ │ └── http_parser.h # HTTP 请求解析器
│ │
│ ├── handler/ # 业务处理器(20 个,均为单文件 inline 函数)
│ │ ├── user_handler.h # 用户注册/登录/资料
│ │ ├── product_handler.h # 商品列表/详情/搜索(Redis 缓存)
│ │ ├── cart_handler.h # 购物车 CRUD
│ │ ├── order_handler.h # 订单全生命周期
│ │ ├── seckill_handler.h # 秒杀核心(Redis 预扣 + 信号量限流)
│ │ ├── coupon_handler.h # 优惠券创建/发放/使用
│ │ ├── review_handler.h # 商品评价
│ │ ├── merchant_handler.h # 商户管理(最大,1764 行)
│ │ ├── admin_dashboard.h # 管理端统计看板
│ │ ├── alipay_handler.h # 支付宝支付(RSA 签名)
│ │ ├── upload_handler.h # 文件上传 + 静态文件服务
│ │ ├── after_sale_handler.h # 售后系统
│ │ ├── ... (共 20+ 个 handler)
│ │
│ ├── db/
│ │ └── connection_pool.h # MySQL 连接池(线程安全、RAII 自动回收)
│ │
│ ├── redis/
│ │ └── redis_client.h # 手写 RESP 协议客户端(零依赖)
│ │
│ ├── utils/
│ │ ├── response.h # HTTP 响应构造
│ │ ├── json_utils.h # JSON 序列化
│ │ └── alipay_config.h # 支付宝 RSA 签名配置
│ │
│ └── threadpool/ # 自研线程池
│ ├── include/
│ │ ├── ThreadPool.h # 线程池主类
│ │ ├── ThreadPool.inl # 模板实现
│ │ ├── ThreadPoolMetrics.h # 性能指标
│ │ ├── TaskInfo.h # 任务信息(优先级、状态、超时)
│ │ └── Logger.h # 日志
│ └── src/
│ ├── ThreadPool.cpp
│ ├── ThreadPoolMetrics.cpp
│ ├── TaskInfo.cpp
│ └── Logger.cpp
│
├── sql/ # 数据库脚本
│ ├── schema.sql # 完整建表 DDL(16 张核心表)
│ ├── seed.sql # 测试数据(用户、分类、商品、商户)
│ ├── seed_fix.sql # 重新播种
│ ├── migration.sql # 数据库迁移
│ ├── migration_v2.sql # v2 迁移
│ ├── seckill.sql # 秒杀相关表
│ └── ... (更多迁移 & 优化脚本)
│
├── er-parts/ # 数据库 ER 图切片
├── er-parts2/ # 重构版 ER 图切片
├── ecommerce-er.dbml # 完整 ER 图 DBML 格式
├── ecommerce-er.md # 完整表结构文档
│
├── Makefile # 构建文件(g++/MinGW)
├── package.json # 前端开发依赖(Playwright 测试)
└── README.md # 本文件
| 依赖 |
版本要求 |
说明 |
| g++ |
8+(支持 C++17) |
Linux 默认自带,Windows 可以用 MinGW/MSYS2 |
| MySQL |
8.0+ |
数据库 |
| Redis |
7.0+ |
缓存/秒杀(可选,禁用时降级为直接查 MySQL) |
| make |
— |
构建工具 |
| 操作系统 |
Linux(推荐) |
Windows 部分兼容 |
git clone https://github.com/jiubao76799/ecommerce-server.git
cd ecommerce-server
make
编译产物为 ecommerce_server 可执行文件。
这会依次执行:
sql/schema.sql — 创建 ecommerce 数据库及所有表
sql/seed.sql — 插入测试数据(分类、商品、用户)
默认 MySQL 密码为 123456(root),如需修改请编辑 Makefile 中的 -p 参数。
或手动运行:
服务器默认监听 0.0.0.0:8080。
[EpollServer] Listening on port 8080
[MySQL] Connected to 127.0.0.1:3306 (pool: 50)
[Redis] Connected to 127.0.0.1:6379
[ThreadPool] Initialized with 4 threads
如果 Redis 不可用,会输出 WARNING: Redis not available, caching disabled,服务器仍可正常运行。
打开浏览器访问 http://localhost:8080
服务器会自动 serve frontend/ 目录下的静态文件。
| 角色 |
账号 |
密码 |
| 普通用户 |
testuser |
123456 |
| 管理员 |
见 seed.sql |
— |
| 商户 |
华为/小米/Apple 等 |
见 seed.sql |
目前所有配置硬编码在 src/main.cpp 中,可通过修改源码自定义:
| 配置项 |
默认值 |
位置 |
| 监听端口 |
8080 |
main.cpp:132 |
| MySQL 主机 |
127.0.0.1 |
connection_pool.h |
| MySQL 用户 |
root |
connection_pool.h |
| MySQL 密码 |
123456 |
connection_pool.h |
| MySQL 端口 |
3306 |
connection_pool.h |
| MySQL 连接池大小 |
50 |
main.cpp:56 |
| Redis 主机 |
127.0.0.1 |
main.cpp(自动探测 WSL 路由) |
| Redis 端口 |
6379 |
main.cpp |
| 线程池大小 |
4 |
main.cpp:49 |
| 上传目录 |
./uploads/ |
upload_handler.h |
| WSL 自动探测 |
是 |
main.cpp:80-120(读 /proc/net/route) |
- 在
src/handler/ 下创建 xxx_handler.h,实现 inline HttpResponse handleXxx(const HttpRequest&) 函数
- 从连接池获取数据库连接:
auto conn = ConnectionPool::getInstance().getConnection();
ConnectionGuard guard(conn);
- 执行 SQL 并构造 JSON 响应
- 在
src/main.cpp 中注册路由:
server.route("GET", "/api/xxx", handleXxx);
Redis 客户端已在 main.cpp 中初始化。在 handler 中使用:
if (RedisClient::getInstance().isAlive()) {
std::string cached = RedisClient::getInstance().execStr("GET key");
if (!cached.empty()) {
// 使用缓存数据
}
}
- 主线程仅做 epoll 事件分发,不处理业务逻辑
- 业务 handler 在工作线程池中执行
- 每个请求的处理过程中独占一个 MySQL 连接(RAII 模式)
- Linux:epoll ET +
accept4 + SOCK_NONBLOCK
- Windows:通过 MinGW 编译,使用
WSAPoll 模拟(降级),WinSock2
- WSL:自动探测 Windows 宿主机 IP 以连接 Redis/MySQL
MIT