飞傲软件 飞傲软件 小程序 · APP · 网站 · 管理系统

做小程序秒杀库存前,先搞懂这三件事

秒杀翻车,九成不是页面卡,是库存扣错了。超卖要赔钱,少卖丢口碑,被刷单则直接亏本。这三件事在动手写代码前就要定下来,后期再改,代价通常是重做。

库存在哪扣,决定了你会不会超卖

很多团队的做法是:用户点下单,先查库存,够就写订单,再减库存。看着合理,其实中间有个空档。同一秒进来两百个请求,都读到“还剩10件”,然后都去写订单。结果就是超卖。

正确的顺序是把扣减动作前置,或者让扣减本身具备原子性。常见做法有两种。一种是数据库行锁,update stock set num = num - 1 where id = ? and num > 0,靠影响行数判断是否成功。写法简单,缺点是并发一高,行锁排队会把连接池占满。另一种是把库存预热到 Redis,用 Lua 脚本做判断加扣减,一次原子执行。速度快,代价是要处理缓存和数据库的一致性,比如扣减成功但订单落库失败,得有回补机制。

怎么选?看你的峰值量级。日常几百人抢,数据库行锁完全够用,别过度设计。真要冲到每秒几千请求,就必须上 Redis 预扣,同时准备一套异步落单加超时释放的逻辑。

有家企业做本地生鲜,第一次秒杀没做预扣,两千份鸡蛋超卖了四百多单。后来改成 Redis 预扣加定时回补,同样的量级稳稳扛住。问题不在技术多高级,在顺序对不对。

限流放在网关还是业务层,关系到系统死活

库存扣对了,也不代表系统能活。秒杀的特点是流量瞬时集中,平时一天一万请求,活动开始一秒来三万。这种形状的流量,单纯堆服务器是划不来的。

限流要分层做。最外层是网关或 CDN 层,把明显的异常请求挡掉,比如同一 IP 高频提交、没有登录态的请求。中间一层是活动维度的令牌桶,按商品分配放行量,只让库存量的一点几倍请求进到后端。最里面才是业务校验,判断是否重复下单、是否黑名单用户。

顺序别倒。见过把校验全放业务层,结果所有请求都打到数据库,慢查询堆起来,整个库跟着一起挂。限流的意义不是拦用户,是保住系统别整体崩掉。

另外,前端的按钮置灰、倒计时这类交互,只是体验优化,不构成防护。有人直接用脚本打接口,绕过页面。真正的防线在后端。

用户点了没付款,库存怎么回去

这是最容易被忽略的一环。下单成功锁定库存,用户不付款,库存一直占着,活动结束还剩一堆,那就等于少卖。

解法是给订单加超时释放。常见设 15 分钟,时间到了还没支付,就把库存加回去。实现上可以用延迟队列,也可以靠定时任务扫过期订单。延迟队列实时性好,但组件多一层维护成本;定时任务实现简单,缺点是释放有延迟,粒度取决于扫描频率。中小活动用定时任务足够,量大了再换。

回补动作必须幂等。网络抖动导致消息重投,同一笔订单回补两次,库存就凭空多出来。做法是在回补前先改订单状态,用状态变更的结果决定要不要加库存,靠数据库唯一约束兜底。

对账也要有。活动结束后拉一遍:初始库存、扣减次数、回补次数、实际成交量,四个数字对不上就说明有漏。这类脚本不复杂,但能提前发现很多隐性 bug。

收尾给三条可执行建议

先算峰值再定架构。把预计参与人数、活动时长、库存量三个数写下来,估算每秒请求量,再决定用数据库锁还是 Redis 预扣。数字不清楚,讨论技术选型没意义。

限流和库存扣减分开设计。前者保系统,后者保数据,混在一起容易两头都做不好。上线前做一次压测,哪怕只是脚本模拟并发,也能暴露大部分问题。

把超时释放和幂等当成必做项,不是可选项。这部分代码量不大,但少了它,活动数据一定对不平。找开发团队时,可以直接问对方这三个问题怎么处理,回答得含糊的,基本没做过真实的高并发电商场景。常州飞傲软件科技有限公司在这类项目上通常会把库存模型和对账脚本一起交付,企业验收时也更容易检查。

相关阅读

推荐阅读

准备好开始了吗?

联系我们免费获取定制开发方案与报价,专业顾问 1 对 1 为您服务。

微信二维码扫码添加微信咨询