author
type
status
date
slug
summary
tags
category
icon
password
消息队列延迟消息
实现步骤
- 订单创建时:将订单信息发送到消息队列(如RocketMQ、RabbitMQ),设置延迟时间(例如30分钟)
- 延迟到期后:消费者收到消息,检查订单状态
- 若订单未支付,执行取消逻辑(释放库存、更新状态为“超时取消”)
- 若订单已支付,忽略消息。
优点
- 高可靠性:消息队列自带持久化和重试机制。
- 实时性强:延迟精度高(例如RocketMQ支持秒级延迟)。
代码示例
Redis过期监听
实现步骤
- 订单创建时:在Redis设置订单ID为key,设置过期时间(例如30分钟)。
- 过期触发事件:Redis监听到key过期后,通知服务处理取消逻辑。
- 检查订单状态:与方案一类似,确保幂等性。
缺点
- 可靠性低:Redis过期事件可能丢失(如服务宕机时)。
- 需兜底补偿:需额外定时任务补查未处理订单。
代码示例(Spring + Redis)
定时任务轮训
实现步骤
- 定时任务:每隔1分钟扫描数据库中status=未支付且创建时间>30分钟的订单。
- 批量处理:对符合条件的订单执行取消逻辑。
代码示例(Spring Scheduler)
缺点
- 性能压力:高频扫描数据库影响性能。
- 时效性差:最大延迟为轮询间隔(例如1分钟)。
时间轮算法
实现步骤
- 初始化时间轮:创建时间轮(例如刻度为1秒,共3600刻度,支持1小时延迟)。
- 订单创建时:将取消任务加入时间轮。
- 到期触发任务:执行取消逻辑,检查订单状态。
优点
- 高性能:适合高并发场景(如10万+订单)。
- 低延迟:任务触发精度高。
代码示例
方案对比
方案 | 可靠性 | 实时性 | 性能 | 实现复杂度 |
消息队列延迟 | 高 | 高 | 高 | 中 |
Redis 过期监听 | 中 | 高 | 高 | 低(需补偿) |
定时任务轮询 | 高 | 低 | 低 | 低 |
时间轮算法 | 中 | 高 | 极高 | 高 |
推荐方案
消息队列延迟消息 + 定时任务补偿
消息队列延迟消息(如RocketMQ) + 定时任务补偿(防止消息丢失)。
关键点
- 幂等性:取消逻辑需支持重复调用(如先检查状态再操作)。
- 事务性:订单状态更新和库存释放需保证原子性(可用本地事务或TCC模式)。
- 监控:记录超时取消成功/失败次数,配置告警。
- 作者:Sean Liu
- 链接:http://liusx.top/article/1f9749a0-584b-806b-8dde-c22198872fb6
- 声明:本文采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。