跳转到内容

Scenario 24: Flash Sale 秒杀系统

你想做一个秒杀活动页面原型,体验倒计时和抢购交互。

  • 活动倒计时(天时分秒)
  • 抢购按钮状态流转(未开始→抢购中→已结束)
  • localStorage记录是否已抢
  • 模拟抢购结果(随机成功/失败)

用HTML+CSS+JS做一个秒杀活动页面。商品信息硬编码(名称、原价、秒杀价、库存100、 活动开始时间设为当前时间+30秒方便测试)。倒计时组件:天:时:分:秒, 倒计时结束前按钮置灰”即将开始”,结束后变红”立即抢购”。 点击抢购:显示loading(1-3秒随机),70%概率成功30%失败。 成功后存localStorage(防止重复抢购),页面显示”已抢到”。 库存数字实时递减(模拟其他人也在抢)。活动结束后显示”已售罄”。

  • 倒计时精确到秒,归零后按钮可点击
  • 抢购成功后不能重复抢
  • 库存数字动态递减
  • 活动结束后正确显示售罄
  • 倒计时实现 → Module: 定时器
  • 按钮状态管理 → Module: UI状态机
  • 前端防重复提交 → Module: 交互优化

V2 — 10人用:后端库存+先到先得

Section titled “V2 — 10人用:后端库存+先到先得”

需要真实的库存管理,保证先到先得,防止超卖。

  • 商品+库存管理
  • 先到先得抢购逻辑
  • 简单限购(每人限1件)
  • 订单创建

Go+Gin后端,SQLite。商品表(id, name, price, seckill_price, stock, start_time, end_time), 订单表(id, user_id, product_id, status, created_at)。 秒杀API(POST /api/seckill):1)检查活动时间 2)检查是否已购买(限购1件) 3)检查库存 4)扣减库存+创建订单(事务)。SQLite事务保证不超卖。 活动管理API:创建/修改秒杀活动。前端页面:活动列表、倒计时、抢购。 抢购结果即时返回(成功/已抢过/售罄/未开始)。

  • 活动时间外无法抢购
  • 同一用户不能重复抢购
  • 库存扣减到0后返回售罄
  • 事务保证不超卖
  • 数据库事务 → Module: 事务基础
  • 限购校验 → Module: 业务规则
  • 接口时间窗口控制 → Module: 活动系统

V3 — 100人用:Redis预扣库存+异步下单

Section titled “V3 — 100人用:Redis预扣库存+异步下单”

并发量上来,数据库直接扛不住,需要Redis做前置拦截。

  • Redis原子扣减库存(不依赖数据库)
  • 异步创建订单(消息队列)
  • 防超卖的完整方案
  • 库存预热机制

活动开始前:管理端”预热”接口将库存从PostgreSQL同步到Redis (SET seckill:{product_id}:stock 100)。秒杀请求处理: 1)Redis SISMEMBER检查限购(seckill:{product_id}:users) 2)Redis Lua脚本原子操作:检查库存>0 → DECR库存 → SADD已购用户 → 返回成功 3)成功后发消息到队列(product_id, user_id) 4)消费者异步创建订单写入PostgreSQL。 秒杀结果查询:先查Redis(是否在已购集合),再查DB(订单状态)。 库存归还:未支付订单15分钟超时,Redis INCR归还库存。

  • Redis Lua脚本原子扣减,并发无超卖
  • 异步订单创建无遗漏
  • 限购集合正确拦截重复请求
  • 超时归还库存后可被他人抢购
  • Redis Lua原子操作 → Module: Redis高级
  • 异步消息队列 → Module: 消息队列
  • 库存一致性方案 → Module: 分布式库存

V4 — 1000人用:多级缓存+限流排队

Section titled “V4 — 1000人用:多级缓存+限流排队”

请求量进一步增大,需要多层防护减轻后端压力。

  • 三级缓存:本地缓存 → Redis → DB
  • 请求限流(令牌桶算法)
  • 排队机制(超出处理能力的请求排队)
  • 活动页面静态化

三级缓存:Go进程内存缓存商品信息和库存状态(sync.Map,10秒TTL), 库存为0后本地标记售罄(后续请求直接返回,不查Redis)。 限流:令牌桶算法(golang.org/x/time/rate),每个商品QPS上限1000, 超限返回429”排队中,请稍后重试”。 排队机制:超出处理能力的请求进入内存队列(channel,容量5000), 消费者按序处理,返回排队位置,前端轮询结果。 活动页面静态化:活动开始前生成静态HTML(含商品信息),通过CDN直接返回, 只有点击”抢购”才请求后端API。

  • 本地缓存售罄标记后不再访问Redis
  • 限流正确拦截超额请求
  • 排队机制返回位置,最终返回结果
  • 静态页面从CDN加载,不压后端
  • 多级缓存策略 → Module: 缓存架构
  • 令牌桶限流 → Module: 限流算法
  • 页面静态化 → Module: 性能优化

大促秒杀,瞬间流量可能是平时的100倍,全链路需要防护。

  • Nginx层限流(第一道防线)
  • 消息队列削峰填谷
  • 静态资源CDN分发
  • 全链路压测验证

Nginx限流配置:limit_req_zone(每IP 10次/秒),超限返回静态排队页面。 活动页面HTML/CSS/JS/图片全部上CDN,用户访问CDN域名,不直接请求源站。 消息队列削峰:秒杀请求先全部写入Kafka,消费者按固定速率(每秒处理2000笔) 消费,超出的自然排队。前端WebSocket获取处理进度。 全链路压测:用wrk/k6模拟10000并发,测试每层的瓶颈。 压测报告:QPS、P50/P99延迟、错误率、资源使用率。 根据压测结果调优:连接池大小、队列消费者数量、Redis连接数。

  • Nginx限流有效拦截过量请求
  • CDN承担90%以上静态资源请求
  • Kafka消费者稳定处理不积压
  • 压测10000并发无系统崩溃
  • P99延迟<2秒
  • Nginx限流配置 → Module: 反向代理
  • CDN加速 → Module: 内容分发
  • 压力测试 → Module: 性能测试

秒杀系统需要全链路高可用,任何环节故障都不能导致资金损失。

  • 库存预热+活动预加载全自动化
  • 熔断+降级+兜底策略
  • 全链路监控+实时告警
  • 弹性伸缩(根据流量自动扩容)

预热自动化:活动开始前30分钟自动执行——库存同步到Redis、静态页面推送CDN、 缓存预热、健康检查。预热状态Dashboard实时展示。 熔断降级:Redis不可用→降级到DB限流模式(QPS降到100);DB不可用→返回静态兜底页 “系统繁忙请稍后”;支付不可用→允许下单但延迟支付。 监控告警:Prometheus采集指标(QPS、延迟、错误率、Redis命中率、队列积压), Grafana Dashboard,错误率>5%或P99>3秒触发PagerDuty告警。 弹性伸缩:Kubernetes HPA根据CPU/QPS自动扩容API Pod, 活动结束后30分钟自动缩容。压测演练:每次大促前1周做全链路压测。

  • 预热全自动化,Dashboard状态可视
  • Redis故障时降级方案自动生效
  • 监控告警<30秒触达
  • 自动扩容在流量上来前完成
  • 全链路无单点故障
  • 全链路高可用 → Module: 系统可靠性
  • 熔断降级策略 → Module: 容错设计
  • 弹性伸缩 → Module: Kubernetes HPA