Java 实现秒杀-订单、库存、支付顺序确定

秒杀三个基本过程:生成订单、减扣库存、用户支付
1、下单减库存
在这里插入图片描述
先创建订单,然后扣除库存,等待用户支付。
这种解决方案,可以保证订单不会超卖,因为创建订单之后就会减库存,这是一个原子操作。
但是会产生一些问题:
1)在极限并发情况下,任何一个内存操作的细节都至关影响性能,尤其像创建订单这种逻辑,一般都需要存储到磁盘数据库的,对数据库的压力是可想而知的;
2)如果用户存在恶意下单的情况,只下单不支付这样库存就会变少,会出现“少卖”,虽然服务端可以限制 IP 和用户的购买订单数量,这也不算是一个好方法。

2 支付减库存
在这里插入图片描述

用户支付了订单再减库存,感觉不会少卖。但是极限并发情况下,用户可能会创建很多订单。
当库存减为零的时候很多用户发现抢到的订单支付不了了,这也就是所谓的“超卖”。也不能避免并发操作数据库磁盘 IO。

3 预扣库存
在这里插入图片描述
上面两种方案得出结论:只要创建订

<think>好的,用户现在问的是关于MQ消费的问题。我需要回顾之前的对话历史,看看有没有相关的上下文。之前用户要求举一个复杂的例子,我介绍了电商订单系统的Facade模式,涉及订单处理、库存管理等子系统的协调。现在用户的问题转向消息队列(MQ)的消费,这可能是在分布式系统或微服务架构中的一个关键组件。 首,我需要确定用户对MQ消费的了解程度。他们可能已经知道MQ的基本概念,但需要更深入的解释,尤其是如何在实际系统中应用,比如在之前的电商例子中MQ如何发挥作用。用户可能想了解MQ消费的机制、常见问题及解决方案,或者最佳实践。 接下来,我应该结构化回答,从基本概念入手,解释什么是MQ消费,然后结合之前的电商案例,展示MQ如何用于解耦系统组件。比如,订单创建后发送消息到MQ,库存服务消费该消息来扣减库存,这样避免直接依赖,提高系统的可靠性和扩展性。 还需要考虑用户可能的痛点,比如消息重复消费、顺序保证、处理失败等。需要解释如何通过幂等性设计、消费者组、死信队列等方法解决这些问题。同时,结合之前的例子,说明在订单系统中如何确保库存扣减的准确性和一致性。 另外,用户可能对具体的MQ产品(如Kafka、RocketMQ、RabbitMQ)感兴趣,但需要保持回答的通用性,除非用户特别指定。还要注意使用中文,保持回答清晰,结构合理,符合之前设定的格式要求,比如分点说明、代码示例等。 最后,总结MQ消费的优势,如异步处理、流量削峰、系统解耦,并指出在复杂系统中的应用场景,呼应之前电商的例子,让用户更好地理解其实际价值。</think>### MQ消费核心解析 消息队列(MQ)消费是分布式系统中实现**异步解耦、流量削峰、可靠传输**的核心机制。以下通过电商订单案例拆解其核心逻辑: --- #### 1. **基础模型** $$ Producer \xrightarrow{Message} Broker \xrightarrow{Push/Pull} Consumer $$ - **Producer**:订单服务生成消息(如`订单创建成功`) - **Broker**:消息中间件(Kafka/RocketMQ/RabbitMQ) - **Consumer**:库存服务、物流服务等订阅消息 --- #### 2. **电商场景案例** **业务需求**:订单支付成功后,需同时触发: - 库存扣减 - 积分计算 - 物流调度 **传统模式问题**: ```java // 强耦合实现(存在性能瓶颈) orderService.paySuccess() { inventoryService.deductStock(); // 同步调用 pointsService.addPoints(); // 同步调用 logisticsService.createTask(); // 同步调用 } ``` **MQ解耦方案**: ```java // 订单服务(生产者) orderService.paySuccess() { mqProducer.send("order_paid", orderId); // 发送消息后立即返回 } // 各子系统消费(消费者) @MQListener(topic="order_paid") void handleOrderPaid(String orderId) { inventoryService.deductStock(orderId); // 库存服务消费 } @MQListener(topic="order_paid") void handleOrderPaid(String orderId) { pointsService.addPoints(orderId); // 积分服务消费 } ``` --- #### 3. **核心消费模式** | 模式 | 特点 | 适用场景 | |---------------|------------------------------|-----------------------| | **集群消费** | 同组消费者均摊消息 | 普通任务处理 | | **广播消费** | 所有消费者收到全量消息 | 配置同步、缓存更新 | | **顺序消费** | 保证分区内消息顺序 | 订单状态变更 | --- #### 4. **关键问题与解决方案** **问题1:重复消费** - **场景**:网络抖动导致消费确认失败,消息重新投递 - **解法**: ```java // 幂等性设计(以库存扣减为例) boolean deductStock(String orderId) { if (redis.exists("deducted:"+orderId)) { // 已处理过 return true; } // 执行真实扣减 redis.setex("deducted:"+orderId, 3600, "1"); // 标记已处理 } ``` **问题2:消息堆积** - **场景**:促销期间订单暴涨,消费速度跟不上生产速度 - **解法**: - 动态扩容消费者实例 - 设置不同优级队列(重要消息优处理) **问题3:事务消息** - **场景**:支付成功消息需要保证本地事务与消息发送的原子性 - **方案**: ```mermaid graph LR A[1.发送半消息] --> B[2.执行本地事务] B --> C{3.事务成功?} C -->|Yes| D[4.提交消息] C -->|No| E[5.回滚消息] ``` --- #### 5. **消费性能优化** 1. **批量消费** ```java // RocketMQ批量消费配置 consumer.setConsumeMessageBatchMaxSize(32); // 单次拉取32条 ``` 2. **推拉模式选择** - Push模式:实时性高(如即时通讯) - Pull模式:可控性强(如大数据处理) 3. **位点管理** ```shell # 重置消费位点(处理积压时使用) ./mqadmin resetOffsetByTime -t order_topic -g inventory_group -s 20231001000000 ``` --- ### 典型应用场景 1. **最终一致性事务**:跨系统数据同步(订单库存→物流) 2. **削峰填谷**:秒杀请求入队列,后端匀速处理 3. **事件驱动架构**:用户注册成功触发邮件/短信通知 --- ### 注意事项 1. **消费延迟监控**:通过`消息生产时间`与`消费时间`差值检测异常 2. **死信队列配置**:处理超过重试次数的"毒药消息" 3. **消息轨迹追踪**:结合TraceId实现全链路追踪 在阿里双11、京东618等场景中,MQ集群日均处理**万亿级消息**,通过精细化消费策略保障系统平稳运行。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值