生成订单30分钟未支付,则自动取消,该怎么实现?
1 数据库轮询
通常是在小型项目中使用,即通过一个线程定时的去扫描数据库,通过订单时间来判断是否有超时的订单,然后进行update或delete等操作.
用quartz来实现的。
1 |
|
2 JDK的延迟队列
利用JDK自带的DelayQueue来实现,这是一个无界阻塞队列,该队列只有在延迟期满的时候才能从中获取元素,放入DelayQueue中的对象,是必须实现Delayed接口的。
3 时间轮算法
1 |
|
优点:效率高,任务触发时间延迟时间比delayQueue低,代码复杂度比delayQueue低。
缺点:
- 服务器重启后,数据全部消失
- 集群扩展相当麻烦
- 因为内存条件限制的原因,比如下单未付款的订单数太多,那么很容易就出现OOM异常
4 redis缓存
该方案使用redis的Keyspace Notifications,中文翻译就是键空间机制,就是利用该机制可以在key失效之后,提供一个回调,实际上是redis会给客户端发送一个消息。
5 使用消息队列
5.1 rabbitmq
死信队列和延迟插件方法。
可以采用rabbitMQ的延时队列。RabbitMQ具有以下两个特性,可以实现延迟队列:
- RabbitMQ可以针对Queue和Message设置 x-message-tt,来控制消息的生存时间,如果超时,则消息变为dead letter
- lRabbitMQ的Queue可以配置x-dead-letter-exchange 和x-dead-letter-routing-key(可选)两个参数,用来控制队列内出现了deadletter,则按照这两个参数重新路由。
优点:高效,可以利用mq的横向扩展,持久化消息增加了可靠性
缺点:依赖mq,增加系统的复杂性和成本
5.2 rocketmq
延时消息用于指定消息发送到消息队列RocketMQ版的服务端后,延时一段时间才被投递到客户端进行消费(例如3秒后才被消费),适用于解决一些消息生产和消费有时间窗口要求的场景,或者通过消息触发延迟任务的场景,类似于延迟队列。
1 |
|
参考文档:
https://mp.weixin.qq.com/s/J6jb_Dt3C49CIjYBTrN4gQ
源码
https://github.com/leellun/javasvc-learn/tree/main/svc-delaytask
rabbitmq死信队列:
生成订单30分钟未支付,则自动取消,该怎么实现?
https://leellun.github.io/2022/03/24/业务场景/2022-03-24-生成订单30分钟未支付,则自动取消,该怎么实现?/