问题定义
去年黑五促销,流量峰值时系统直接雪崩。监控大屏一片红色,下单接口响应时间从 200ms 飙升到 30 秒,超时率超过 90%。活动才开始半小时,客服就收到几十个投诉,用户反馈"下单页面打不开"。
当时系统架构很简单:一台 2 核 4G 的云服务器,Node.js 单实例,MySQL 单库。预估 QPS 撑死 50,结果活动峰值 QPS 跑到 800+,直接原地爆炸。
初步诊断
先看的数据库。慢查询日志显示有个订单列表查询耗时 8 秒,SQL 是全表扫描,没有索引:
SELECT * FROM orders
WHERE status != 'closed'
ORDER BY created_at DESC
LIMIT 100;orders 表当时有 80 万数据,没有 status 和 created_at 的联合索引。另外还有个问题是 N+1 查询,订单列表接口里对每个订单又单独查了一次商品详情。
快速修复
第一步加了索引,查询降到 200ms:
ALTER TABLE orders ADD INDEX idx_status_created (status, created_at DESC);第二步用了 Redis 做缓存,订单列表接口加了一层内存缓存:
const orderList = await cache.get(`order_list:${userId}`);
if (!orderList) {
orderList = await db.queryOrders(userId);
await cache.setex(`order_list:${userId}`, 60, orderList);
}第三步把 N+1 查询改成 JOIN 或者用 IN 批量查,避免循环查库。
这套组合拳打完,接口响应降到 500ms 以内,QPS 支撑到 300+。
后续优化
短期应急解决了,但知道这不是长久之计。后来做了几件事:
加了 MongoDB 存商品详情,减轻 MySQL 压力。上了消息队列,下单请求先入队异步处理,接口秒级响应。迁移到多实例部署,前端加负载均衡。
整个优化周期大概两个月,QPS 从 50 提升到 500,扩容到 4 台 4 核 8G 的集群。成本从月均 3000 涨到 8000,但 GMV 翻了 6 倍,ROI 是正的。
血泪教训
做高并发场景的代购系统,有几点心得:
一是数据库索引必须提前建,别等出问题了再临时抱佛脚。二是缓存要用对地方,读多写少的场景收益很明显。三是提前做压测,别拍脑袋预估容量,黑五这种节点流量真的不好猜。
如果觉得自己维护这套架构太费劲,可以考虑用现成的代购系统来扛流量,把精力放在运营和选品上,技术的事交给专业的人。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用。你还可以使用@来通知其他用户。