《淘宝双11同款:基于 Sentinel 的微服务流量防卫兵实战》

简介: 电商库存防超卖是高并发核心面试题,本文详解超卖成因、三级防护(Redis预扣+Lua原子操作+DB乐观锁)、三种分布式锁对比及幂等设计,兼顾技术深度与面试表达。

这个问题是电商面试中的高频题,涉及业务一致性与分布式系统核心技术。下面我将为你撰写一篇结构清晰、技术深入的文章,既适合学习,也适合面试准备。

🛒 《面试官:说说电商库存扣减如何防超卖?分布式锁的三种实现》

“秒杀不到,库存没了;秒杀到了,库存却超了。” —— 这是电商最怕的事故之一。

在电商系统中,库存扣减是核心业务,一旦出错,轻则用户投诉,重则资损赔偿。而高并发场景下,如何防止“超卖”(Over-Selling)?答案离不开:分布式锁 + 原子操作 + 幂等性设计。

本文将深入讲解:

  1. 超卖是如何发生的?
  2. 如何设计安全的库存扣减流程?
  3. 三种主流分布式锁实现方式对比
  4. 面试加分项:Redisson、ZooKeeper、数据库锁

一、什么是“超卖”?

超卖:实际卖出的商品数量 > 库存数量。

示例场景:

• 商品库存:10 件

• 同时 15 人下单成功 → 超卖 5 件

• 结果:无法发货,引发客诉、退款、平台信誉受损

二、超卖的根本原因

原因 说明

并发读写未加锁 多个线程同时读取库存为 10,各自扣减,最终扣成负数

非原子操作 查询库存 + 判断 + 扣减 三步分离,中间被插队

缓存与DB不一致 Redis 预扣库存,但 DB 更新失败,未回滚

重试机制不当 消息重试导致重复扣减

三、正确库存扣减流程设计

✅ 核心原则:原子性 + 幂等性 + 最终一致性

推荐流程(以秒杀为例):

  1. 用户点击购买 → 进入排队队列
  2. 检查库存(Redis 预扣)
  3. 扣减 Redis 库存(Lua 脚本保证原子性)
  4. 发送 MQ 消息 → 异步扣减数据库
  5. 返回“抢购中”状态
  6. 消费者消费消息 → 扣减 DB 库存
  7. 扣减成功 → 通知用户付款
  8. 超时未付款 → 回补库存(Redis + DB)

⚠️ 关键点:所有“读-改-写”操作必须原子化,不能拆开!

四、分布式锁的三种实现方式

问:如何保证同一时间只有一个请求能扣减某商品的库存?

答:用分布式锁,把“扣减”变成串行操作。

方式一:基于 Redis 的分布式锁(最常用)

实现方式:SET key value NX PX 30000

// 加锁
String lockKey = "stock:lock:" + productId;
String requestId = UUID.randomUUID().toString();
Boolean locked = redisTemplate.opsForValue()
.setIfAbsent(lockKey, requestId, 30, TimeUnit.SECONDS);

if (locked) {
try {
// 执行业务:扣减库存
int remain = stockService.deductStock(productId, quantity);
if (remain < 0) throw new RuntimeException("库存不足");
} finally {
// 释放锁:Lua 保证只有自己能删
String script = "if redis.call('get',KEYS[1]) == ARGV[1] then return redis.call('del',KEYS[1]) else return 0 end";
redisTemplate.execute(new DefaultRedisScript<>(script, Long.class), Arrays.asList(lockKey), requestId);
}
} else {
throw new RuntimeException("系统繁忙,请重试");
}

✅ 优点:

• 高性能(内存操作)

• 支持过期自动释放

• 广泛使用(Redisson 封装)

❌ 缺点:

• 主从切换可能导致锁失效(需用 RedLock)

• 时间漂移问题(锁过期但任务未完成)

方式二:基于 ZooKeeper 的分布式锁(高可靠)

原理:临时顺序节点 + Watch 机制

// Curator 框架示例
InterProcessMutex lock = new InterProcessMutex(client, "/locks/stock_" + productId);
try {
if (lock.acquire(10, TimeUnit.SECONDS)) {
// 扣减库存
stockMapper.decrease(productId, quantity);
}
} finally {
lock.release();
}

✅ 优点:

• 强一致性(ZAB 协议)

• 锁自动释放(会话断开即删除节点)

• 公平锁支持好

❌ 缺点:

• 性能低于 Redis

• 运维成本高(需部署 ZK 集群)

方式三:基于数据库的分布式锁(最简单,但不推荐高并发)

方式 A:唯一索引 + INSERT 抢占

CREATE TABLE distributed_lock (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
lock_key VARCHAR(64) NOT NULL UNIQUE,
owner_id VARCHAR(64),
expire_time DATETIME
);

抢占锁:
INSERT INTO distributed_lock (lock_key, owner_id, expire_time)
VALUES ('stock_123', 'user_456', NOW() + INTERVAL 30 SECOND);
-- 主键冲突则抢占失败

释放锁:DELETE FROM distributed_lock WHERE lock_key='stock_123' AND owner_id='user_456'

方式 B:UPDATE 乐观锁(更推荐)

UPDATE stock SET quantity = quantity - #{quantity}, version = version + 1
WHERE product_id = #{productId} AND quantity >= #{quantity};

配合版本号或 CAS 操作,天然防超卖。

✅ 优点:

• 无需额外中间件

• 简单易懂,适合中小项目

❌ 缺点:

• 性能差(DB 瓶颈)

• 锁持有时间长会阻塞连接池

• 不支持非阻塞获取

五、三种锁对比表(面试必备)

特性 Redis 锁 ZooKeeper 锁 数据库锁

一致性 最终一致 强一致 强一致

性能 ⭐⭐⭐⭐ ⭐⭐ ⭐

可靠性 中(需 RedLock) 高 低

实现复杂度 中 高 低

适用场景 秒杀、缓存击穿防护 金融、分布式协调 低频扣减、简单业务

推荐框架 Redisson Curator MyBatis + SQL

六、进阶:如何用 Lua + Redis 彻底避免超卖?(无锁胜有锁)

原子脚本示例(Redis 中执行):

-- KEYS[1]: stock:{productId}
-- ARGV[1]: 扣减数量

local stock = tonumber(redis.call('GET', KEYS[1]))
if stock >= tonumber(ARGV[1]) then
redis.call('DECRBY', KEYS[1], ARGV[1])
return stock - tonumber(ARGV[1])
else
return -1 -- 库存不足
end

Java 调用:
DefaultRedisScript script = new DefaultRedisScript<>(luaScript, Long.class);
Long remain = redisTemplate.execute(script, Collections.singletonList(key), String.valueOf(quantity));
if (remain != null && remain >= 0) {
// 扣减成功,继续下单流程
}

👉 优势:无需分布式锁,单条命令完成判断+扣减,天然原子!

七、面试加分回答模板

面试官:说说电商库存扣减如何防超卖?

你可以这样回答:

“我们采用‘三级防护’机制:

  1. 前端限流 + 按钮置灰,减少无效请求;
  1. Redis 预扣库存,通过 Lua 脚本保证原子性,避免并发超卖;

  2. 数据库最终扣减,使用乐观锁(version 或 CAS)确保数据一致;

  3. 为防止重复扣减,我们引入幂等性设计,通过订单号 + 状态机控制;

  4. 在高并发场景下,我们使用 Redisson 分布式锁 对关键资源加锁,确保同一时间只有一个请求能操作某商品库存。

此外,我们还设计了库存回补机制:用户超时未付款,通过定时任务将 Redis 和 DB 库存同步回补。”

八、避坑指南

坑 解决方案

锁忘记释放 用 try-finally 或看门狗机制(Redisson)

锁过期但任务没完 设置合理的过期时间 + 看门狗续期

主从切换丢锁 使用 RedLock 或 ZooKeeper

缓存与 DB 不一致 采用“Cache-Aside + 消息补偿”模式

重复扣减 订单号幂等校验 + 状态机(待支付→已支付)

九、总结

技术点 作用

分布式锁 控制并发,避免同时操作

原子操作(Lua) 替代锁,提升性能

乐观锁(CAS) 保证 DB 层不超卖

幂等性 防止重复扣减

最终一致性 通过 MQ 异步同步数据

十、推荐学习资源

• Redisson 官方文档:https://redisson.org/

• Curator 锁实现:https://curator.apache.org/

• 阿里《Java 开发手册》:关于锁的使用规范

• 极客时间《分布式技术原理与实战》

需要我为你画一个“库存防超卖全链路流程图”,用 Mermaid 或文字描述,方便你在面试中手绘展示吗?这样可以让回答更直观,提升印象分。

相关文章
|
2月前
|
缓存 NoSQL Java
《面试官:说说电商库存扣减如何防超卖?分布式锁的三种实现》
这是一道电商高频面试题,聚焦库存防超卖与分布式锁实战。提供可直接背诵的“三段式”方案(Redis Lua预扣 + MQ异步 + DB乐观锁),详解Redis/ZK/DB三种锁原理、源码级实现、避坑指南及大厂选型逻辑,兼顾技术深度与落地能力。(239字)
|
2月前
|
人工智能 JSON 机器人
让龙虾成为你的“公众号分身” | 阿里云服务器玩Openclaw
本文带你零成本玩转OpenClaw:学生认证白嫖6个月阿里云服务器,手把手配置飞书机器人、接入免费/高性价比AI模型(NVIDIA/通义),并打造微信公众号“全自动分身”——实时抓热榜、AI选题拆解、一键发布草稿,5分钟完成热点→文章全流程!
46084 163
让龙虾成为你的“公众号分身” | 阿里云服务器玩Openclaw
|
SQL 关系型数据库 MySQL
【MySQL入门到精通-黑马程序员】MySQL基础篇-SQL概述及DDL
(精度指数的所有位数;标度指小数点后数的位数) 字符串类型
447 0
|
Kubernetes 负载均衡 网络协议
k8s中部署springboot项目
k8s中部署springboot项目
1479 0
|
5月前
|
人工智能 运维 安全
技术深析快手直播安全事件:为什么大量违规直播“关不掉”?
快手直播安全事件暴露了高并发下账号权限、风控与审核系统的系统性失效。对测试开发而言,需从功能验证转向系统性防控,强化极端场景测试、高负载审核链路验证及熔断机制演练,提升对复杂风险的预判与拦截能力。
|
29天前
|
人工智能 运维 机器人
保姆级图文教程|阿里云轻量服务器部署OpenClaw、Discord集成与千问Qwen3.6-Plus全配置指南
本文完整覆盖从**轻量服务器实例创建、端口放行、OpenClaw初始化、Discord深度集成、大模型API配置、技能扩展、运维排错**的全流程,所有步骤均为2026年4月最新实践,配合详细的避坑指南与运维命令,可解决新手部署中90%以上的问题。遵循**“选对海外地域、放通核心端口、准确配置凭证、及时重启服务、使用专用小号”**五大核心原则,即可实现OpenClaw 7×24小时稳定运行,通过Discord随时随地与专属AI助理交互,高效完成社群管理、内容创作、代码编写、信息查询等各类任务,快速落地AI智能化应用场景,让AI真正成为个人与团队的高效生产力工具。
403 4
|
2月前
|
架构师 Java 程序员
SpringBoot 整合 Nacos,让微服务像外卖点单一样简单
可以试试,让你的微服务像外卖一样:随时点单,准时送达,还能实时跟踪进度!好的架构师就像好的厨师:不仅要会做菜,还要懂得如何高效管理厨房!Nacos就是你的"智能厨房管理系统"!
246 0
|
2月前
|
人工智能 安全 API
OpenClaw(Clawdbot)保姆级实战宝典:阿里云+本地部署流程+Coding Plan配置及8大应用场景测评
2026年开年以来,开源AI智能体项目OpenClaw(原名Clawdbot/Moltbot)在币圈与科技圈持续掀起热潮,GitHub星标一度飙升至18万+,其衍生的Moltbook AI论坛更是上演了十余万AI智能体自发组建“数字宗教”、推选43位AI先知的科幻场景。与传统聊天机器人不同,OpenClaw实现了从“建议者”到“执行者”的跨越,凭借高系统权限、24/7持续运行能力成为新一代“数字员工”,而2026年阿里云对其的深度适配,以及全平台本地部署方案的完善,更是让这款工具的应用边界进一步拓宽。本文将深度解析OpenClaw的核心能力与8大最佳应用场景,同时带来2026年阿里云部署、Ma
1147 3
|
5月前
|
Web App开发 编解码 边缘计算
技术角度解析快手22日出现大面积不合规内容原理·卓伊凡
技术角度解析快手22日出现大面积不合规内容原理·卓伊凡
1023 0