核心思路是将库存操作移至内存,用缓存扛读、原子操作控写、队列削峰、锁保安全,并辅以分层防护和异步落库;秒杀前预热库存至redis,扣减时直接用decr原子指令操作字符串类型库存键。

核心思路是把库存操作从数据库“搬”到内存里做,用缓存扛读、用原子操作控写、用队列削峰、用锁保安全,再配上分层防护和异步落库,整个链路就稳了。
库存预热 + Redis 原子扣减
秒杀开始前,把商品 ID、初始库存、活动时间等关键信息全加载进 Redis,避免开抢时查库。扣库存不用先查再减,直接用 DECR 或 DECRBY 操作:
- 库存字段设为字符串类型,比如 seckill:stock:1001
- 执行 DECR seckill:stock:1001,返回值就是扣减后的剩余数
- 若返回值
这个过程天然原子,不依赖事务,毫秒级响应,彻底避开数据库行锁竞争。
分布式锁 + 防重提交双保险
仅靠 Redis 扣减还不够——万一用户连点两次、或脚本重放请求,可能重复扣减成功。所以要在业务入口加一层控制:
- 用 Redisson 的 RLock 对商品 ID 加锁,超时自动释放,防止死锁
- 同时在前端生成唯一请求 ID(如 UUID),后端用 Redis 的 SETNX 记录已处理 ID,5 分钟内相同 ID 直接拦截
- 两个机制叠加,既防并发冲突,也防重复提交
消息队列异步下单 + 最终一致性
秒杀成功只代表“抢到了资格”,不代表订单立刻入库。真实订单创建要异步化:
- 扣减成功后,把用户 ID、商品 ID、价格等必要字段发到 Kafka/RocketMQ
- 下游消费服务按顺序处理,生成订单、扣款、发通知
- 数据库写失败可重试,不影响前端响应;库存扣减结果通过 Redis 缓存+过期时间兜底,保证最终一致
分层限流 + 熔断降级
不是所有流量都该进系统,得在入口层层过滤:
- Nginx 层用 limit_req 控制单 IP QPS,防恶意刷量
- 网关(如 Spring Cloud Gateway)基于用户 ID 或 token 做令牌桶限流
- 应用层对秒杀接口加 Sentinel 熔断规则:异常比例超 30% 或 RT 超 500ms,自动降级,返回“稍后再试”页面
- 数据库连接池、Redis 连接池都设合理上限,避免资源耗尽雪崩
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











