
1) 【一句话结论】:采用“最终一致性+本地消息表+分布式事务(Saga模式)”架构,结合跨仓库最小剩余库存优先算法(考虑电子硬件运输成本),通过乐观锁/悲观锁动态控制并发,确保多仓库库存数据一致,高效处理多门店并发下单。
2) 【原理/概念讲解】:分布式系统一致性挑战:库存系统需避免超卖,但分布式事务(如两阶段提交)性能低,故采用最终一致性。本地消息表(如MySQL表)存储库存更新消息,类比“订单的收据”,确保系统故障时消息不丢失。幂等性设计:消息唯一标识(时间戳+订单号+序列号),避免重复扣减。并发控制:乐观锁(版本号)适用于高并发(冲突率低,性能高,如秒杀),悲观锁(行锁)适用于低并发(保证原子性,避免阻塞)。跨仓库算法:最小剩余库存优先,优先选择剩余库存最少的仓库扣减;对于电子硬件(体积大、重量重),可结合仓库的运输距离或库存周转率,优化算法权重(如优先选择距离近的仓库,降低物流成本)。
3) 【对比与适用场景】:
| 方案类型 | 定义 | 特性 | 使用场景 | 注意点 |
|---|---|---|---|---|
| 最终一致性 | 异步消息处理,允许延迟 | 延迟容忍,高并发,低延迟 | 电商订单、库存(允许1-2秒延迟,不影响体验) | 需设计幂等性 |
| 强一致性(分布式事务) | 立即数据一致 | 原子性,立即生效 | 金融交易(不允许超卖) | 性能低,可能阻塞 |
| 乐观锁 | 基于版本号冲突回滚 | 高并发冲突率低,性能高 | 电商秒杀 | 低并发冲突率低 |
| 悲观锁 | 数据库行锁 | 保证原子性,低并发性能高 | 日常订单 | 高并发可能导致阻塞 |
4) 【示例】:订单服务下单流程(伪代码):
def place_order(order_id, product_id, quantity, warehouse_id):
# 检查缓存和数据库库存
cache_stock = redis.get(f"stock:{product_id}")
if cache_stock < quantity: return "库存不足"
db_stock = db.get_stock(product_id, warehouse_id)
if db_stock < quantity: return "库存不足"
# 调用库存服务扣减库存(事务中)
result = stock_service.reduce_stock(product_id, quantity, warehouse_id)
if result == "success":
kafka_producer.send("stock_update", value={"order_id": order_id, "product_id": product_id, "quantity": quantity, "warehouse_id": warehouse_id})
local_msg.insert({"msg_id": f"{order_id}-{uuid()}", "order_id": order_id, "product_id": product_id, "quantity": quantity, "warehouse_id": warehouse_id})
return "下单成功"
return "库存不足"
库存服务处理库存扣减(事务中):
def reduce_stock(product_id, quantity, warehouse_id):
with db.begin(): # 数据库事务
# 更新仓库库存
db.update_warehouse_stock(warehouse_id, -quantity)
# 写入本地消息表
local_msg.insert({"msg_id": f"{order_id}-{uuid()}", "product_id": product_id, "quantity": quantity, "warehouse_id": warehouse_id})
return "success"
订单服务消费消息后,更新订单状态为“已扣减库存”,删除消息记录;若消费失败,重试3次,失败则标记订单为“库存扣减失败”。
5) 【面试口播版答案】:面试官您好,针对乐歌股份电子硬件产品的库存管理,我设计的方案核心是“最终一致性+本地消息表+分布式事务(Saga模式)”,结合跨仓库最小剩余库存算法(考虑产品体积大、运输成本,优化库存分配)。系统通过Redis缓存热点库存,订单服务下单时先检查缓存和数据库,足够则调用库存服务扣减库存。库存服务检查各仓库库存(用优先队列按剩余库存排序)选择最优仓库,事务中更新库存并写入本地消息表。高并发用乐观锁(版本号)避免冲突,低并发用悲观锁(行锁)保证原子性。本地消息表确保消息不丢失,消费失败后重试3次,失败进入死信队列。这样既能保证多仓库库存一致,又能应对多门店并发下单,避免超卖。
6) 【追问清单】:
7) 【常见坑/雷区】: