面试官:如何设计一个电商秒杀系统

410 阅读4分钟

以下是电商秒杀系统的详细架构设计与核心组件功能解析,涵盖前端到后端全链路技术方案,结合高并发场景优化策略:


一、前端优化层

1. ​静态资源优化

  • 页面静态化:将商品描述、图片等固定内容生成静态HTML文件,减少服务端动态渲染压力。
  • CDN加速:将静态资源分发至全球节点,降低用户访问延迟(如商品页面加载时间从500ms降至50ms)。
  • 动态JS控制:倒计时结束时动态加载秒杀按钮逻辑,通过随机参数(如version=20250518)强制CDN更新。

2. ​请求拦截

  • 按钮置灰:通过JS在秒杀开始前禁用按钮,防止无效点击。
  • 频率限制:客户端10秒内仅允许1次请求(如滑动窗口算法),并生成加密Token供服务端验证。
  • 验证码机制:引入滑块或算术验证码拦截机器人(如网页5%流量触发验证码)。

二、服务端架构层

1. ​流量接入层

  • 负载均衡:使用Nginx或云厂商SLB实现IP哈希/加权轮询,支持横向扩展至千台服务器。

  • API网关

    • 鉴权:验证用户Token合法性(JWT或OAuth2)。
    • 限流:基于令牌桶算法限制用户维度请求(如1000次/分钟)。
    • 路由分发:按商品ID分片路由至不同集群。

2. ​缓存层(核心组件)​

  • Redis集群

    • 库存预扣减:通过DECR原子操作扣减库存,Lua脚本保证原子性(如if redis.call('GET', stock_key) > 0 then redis.call('DECR', stock_key))。
    • 热点数据缓存:商品信息、用户黑名单等(缓存命中率>99%)。
    • 分布式锁:Redisson实现秒杀资格锁(如用户ID+商品ID为Key)。

3. ​异步处理层

  • 消息队列

    • 削峰填谷:RocketMQ/Kafka承接峰值流量(如100万QPS),按批次消费(如每批1000条)。
    • 订单异步生成:消息体包含用户ID、商品ID、秒杀Token,消费者校验后写入数据库。

三、库存与订单核心层

1. ​库存管理

  • 分桶策略:将1000件库存拆分为10个桶(如bucket_1~bucket_10),分散并发压力。
  • 预扣库存:下单时预扣Redis库存,支付成功后同步至数据库(防止超卖)。
  • 库存回滚:MQ消息消费失败时通过补偿Job回滚库存(如T+1定时任务)。

2. ​订单服务

  • 幂等设计:基于唯一Token(UUID)防止重复下单。
  • 分库分表:按用户ID哈希分库,单表容量控制在500万(如order_00~order_15)。
  • 热点订单优化:MySQL使用内存引擎表(如MemSQL)处理高频写入。

四、高可用与容灾

1. ​限流熔断

  • Sentinel熔断:当服务错误率>50%时触发熔断,降级返回“活动火爆”。
  • 动态扩容:基于Kubernetes HPA自动扩展Pod(CPU利用率>80%触发)。

2. ​降级策略

  • 静态降级:直接返回缓存库存状态(如“已售罄”)。
  • 流量拦截:Nginx层拦截90%请求,仅放行10%至后端。

3. ​监控与告警

  • Metrics采集:Prometheus监控Redis连接数、MQ堆积量等指标。
  • 全链路追踪:SkyWalking跟踪请求链路(如网关→Redis→MQ→DB)。

五、业务侧优化

1. ​请求分散

  • 分时段秒杀:将活动拆分为多批次(如10:00、14:00、18:00),降低瞬时压力。
  • 答题验证码:强制用户完成简单计算(如“15+7=”),延迟机器人请求。

2. ​数据一致性

  • 最终一致性:通过Binlog同步Redis与MySQL库存(如Canal监听变更)。
  • 对账补偿:每日凌晨校验Redis与DB库存差异,自动修正。

总结

该架构通过前端拦截-缓存削峰-异步解耦-库存分治四层设计,实现每秒百万级请求处理能力。核心在于将90%的流量拦截在前端和缓存层,仅10%请求进入数据库,结合业务优化(如分时段、验证码)进一步降低技术复杂度。实际落地时需根据业务规模选择组件(中小场景可用Redis+MQ,超大规模需引入分库分表+分布式事务)。