问题定义

去年黑五促销,流量峰值时系统直接雪崩。监控大屏一片红色,下单接口响应时间从 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 是正的。

血泪教训

做高并发场景的代购系统,有几点心得:

一是数据库索引必须提前建,别等出问题了再临时抱佛脚。二是缓存要用对地方,读多写少的场景收益很明显。三是提前做压测,别拍脑袋预估容量,黑五这种节点流量真的不好猜。

如果觉得自己维护这套架构太费劲,可以考虑用现成的代购系统来扛流量,把精力放在运营和选品上,技术的事交给专业的人。


yanmoheluo
1 声望1 粉丝

引用和评论

0 条评论