如何实现类似订单到期未支付自动关闭的功能?这6种方案任你挑选( 二 )


总结:redis的过期订阅相比于其他方案没有太大的优势,在实际生产环境中,用得相对较少 。
4,Redisson分布式延迟队列RDelayedQueue
Redisson是一个基于redis实现的JAVA 驻内存数据网格,它不仅提供了一系列的分布式的Java常用对象,还提供了许多分布式服务 。
Redisson除了提供我们常用的分布式锁外,还提供了一个分布式延迟队列RDelayedQueue,他是一种基于zset结构实现的延迟队列,其实现类是RedissonDelayedQueue 。

如何实现类似订单到期未支付自动关闭的功能?这6种方案任你挑选

文章插图
 
优点:使用简单,并且其实现类中大量使用lua脚本保证其原子性,不会有并发重复问题 。
缺点:需要依赖redis(如果这算一种缺点的话) 。
总结:Redisson是redis官方推荐的JAVA客户端,提供了很多常用的功能,使用简单、高效,推荐大家尝试使用 。
5,RocketMQ延迟消息
延迟消息,当消息写入到Broker后,不会立刻被消费者消费,需要等待指定的时长后才可被消费处理的消息,称为延时消息 。
 
在订单创建之后,我们就可以把订单作为一条消息投递到rocketmq,并将延迟时间设置为30分钟,这样,30分钟后我们定义的consumer就可以消费到这条消息,然后检查用户是否支付了这个订单 。
通过延迟消息,我们就可以将业务解耦,极大地简化我们的代码逻辑 。
优点:可以使代码逻辑清晰,系统之间完全解耦,只需关注生产及消费消息即可 。另外其吞吐量极高,最多可以支撑万亿级的数据量 。
缺点:相对来说mq是重量级的组件,引入mq之后,随之而来的消息丢失、幂等性问题等都加深了系统的复杂度 。
总结:通过mq进行系统业务解耦,以及对系统性能削峰填谷已经是当前高性能系统的标配 。
6,RabbitMQ死信队列
除了RocketMQ的延迟队列,RabbitMQ的死信队列也可以实现消息延迟功能 。
当RabbitMQ中的一条正常消息,因为过了存活时间(TTL过期)、队列长度超限、被消费者拒绝等原因无法被消费时,就会被当成一条死信消息,投递到死信队列 。
基于这样的机制,我们可以给消息设置一个ttl,然后故意不消费消息,等消息过期就会进入死信队列,我们再消费死信队列即可 。
通过这样的方式,就可以达到同RocketMQ延迟消息一样的效果 。
优点:同RocketMQ一样,RabbitMQ同样可以使业务解耦,基于其集群的扩展性,也可以实现高可用、高性能的目标 。
缺点:死信队列本质还是一个队列,队列都是先进先出,如果队头的消息过期时间比较长,就会导致后面过期的消息无法得到及时消费,造成消息阻塞 。
总结:除了增加系统复杂度之外,死信队列的阻塞问题也是需要我们重点关注的 。
最后
本文介绍了常见的6种实现订单关闭的方案,不同的方案都有其适用的场景,各自的优缺点也不尽相同,大家可以根据自己的业务场景,选择合适的方案 。
如果本文中没有提到你熟悉的技术方案,也欢迎在评论区分享给大家,期待共同学习进步 。
写文不易,朋友们帮忙点点赞和关注吧,谢谢 。




推荐阅读