您当前的位置:首页 > 电脑百科 > 数据库 > Redis

建议不要使用,redis过期监听实现关闭订单

时间:2022-06-21 14:39:09  来源:博客园  作者:海椰人

电商、支付等领域,往往会有这样的场景,用户下单后放弃支付了,那这笔订单会在指定的时间段后进行关闭操作,细心的你一定发现了像某宝、某东都有这样的逻辑,而且时间很准确,误差在1s内;那他们是怎么实现的呢?

一般实现的方法有几种:

  1. 使用 rocketmq、rabbitmq、pulsar 等消息队列的延时投递功能
  2. 使用 redisson 提供的 DelayedQueue

有一些方案虽然广为流传但存在着致命缺陷,不要用来实现延时任务

  1. 使用 redis 的过期监听
  2. 使用 rabbitmq 的死信队列
  3. 使用非持久化的时间轮

redis 过期监听#

在 Redis 官方手册的keyspace-notifications: timing-of-expired-events中明确指出:

Basically expired events are generated when the Redis server deletes the key and not when the time to live theoretically reaches the value of zero

redis 自动过期的实现方式是:定时任务离线扫描并删除部分过期键;在访问键时惰性检查是否过期并删除过期键。redis 从未保证会在设定的过期时间立即删除并发送过期通知。实际上,过期通知晚于设定的过期时间数分钟的情况也比较常见。

此外键空间通知采用的是发送即忘(fire and forget)策略,并不像消息队列一样保证送达。当订阅事件的客户端会丢失所有在断线期间所有分发给它的事件。

这是一种比定时扫描数据库更 “LOW” 的解决方案,请不要使用。

有另一位大佬做了测试 请勿过度依赖Redis的过期监听, 有兴趣的朋友可以自行查阅。

rabbitmq 死信#

死信(Dead Letter) 是 rabbitmq 提供的一种机制。当一条消息满足下列条件之一那么它会成为死信:

  • 消息被否定确认(如channel.basicNack) 并且此时requeue 属性被设置为false。
  • 消息在队列的存活时间超过设置的TTL时间
  • 消息队列的消息数量已经超过最大队列长度

若配置了死信队列,死信会被 rabbitmq 投到死信队列中。

在 rabbitmq 中创建死信队列的操作流程大概是:

  • 创建一个交换机作为死信交换机
  • 在业务队列中配置 x-dead-letter-exchange 和 x-dead-letter-routing-key,将第一步的交换机设为业务队列的死信交换机
  • 在死信交换机上创建队列,并监听此队列

死信队列的设计目的是为了存储没有被正常消费的消息,便于排查和重新投递。死信队列同样也没有对投递时间做出保证,在第一条消息成为死信之前,后面的消息即使过期也不会投递为死信

为了解决这个问题,rabbit 官方推出了延迟投递插件
rabbitmq-delayed-message-exchange ,推荐使用官方插件来做延时消息。

这里说点题外话,使用 redis 过期监听或者 rabbitmq 死信队列做延时任务都是以设计者预想之外的方式使用中间件,这种出其不意必自毙的行为通常会存在某些隐患,比如缺乏一致性和可靠性保证,吞吐量较低、资源泄漏等。比较出名的一个事例是很多人使用 redis 的 list 作为消息队列,以致于最后作者看不下去写了 disque 并最后演变为 redis stream。工作中还是尽量不要滥用中间件,用专业的组件做专业的事

时间轮#

时间轮是一种很优秀的定时任务的数据结构,然而绝大多数时间轮实现是纯内存没有持久化的。运行时间轮的进程崩溃之后其中所有的任务都会灰飞烟灭,所以奉劝各位勇士谨慎使用。

redisson delayqueue#

redisson delayqueue 是一种基于 redis zset 结构的延时队列实现。delayqueue 中有一个名为 timeoutSetName 的有序集合,其中元素的 score 为投递时间戳。delayqueue 会定时使用 zrangebyscore 扫描已到投递时间的消息,然后把它们移动到就绪消息列表中。

delayqueue 保证 redis 不崩溃的情况下不会丢失消息,在没有更好的解决方案时不妨一试。

在数据库索引设计良好的情况下,定时扫描数据库中未完成的订单产生的开销并没有想象中那么大。在使用 redisson delayqueue 等定时任务中间件时可以同时使用扫描数据库的方法作为补偿机制,避免中间件故障造成任务丢失。

结论#

  1. 首先推荐使用 rocketmq、pulsar 等拥有定时投递功能的消息队列。
  2. 在不方便获得专业消息队列时可以考虑使用 redisson delayqueue 等基于 redis 的延时队列方案,但要为 redis 崩溃等情况设计补偿保护机制。
  3. 在无法使用 redisson delayqueue 等方案时可以考虑使用时间轮。由于时间轮重启远比 redis 重启要频繁,定时扫库等保护机制更为重要。
  4. 永远不要使用 redis 过期监听实现定时任务。

文章来自
https://www.cnblogs.com/Finley/p/16395466.html



Tags:redis   点击:()  评论:()
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,如有任何标注错误或版权侵犯请与我们联系(Email:2595517585@qq.com),我们将及时更正、删除,谢谢。
▌相关推荐
在电商、支付等领域,往往会有这样的场景,用户下单后放弃支付了,那这笔订单会在指定的时间段后进行关闭操作,细心的你一定发现了像某宝、某东都有这样的逻辑,而且时间很准确,误差在...【详细内容】
2022-06-21  Tags: redis  点击:(0)  评论:(0)  加入收藏
Redis 是最流行的 NoSQL 数据库是解决方案之一,而 Java 是世界上最流行(注意,我没有说“最好”)的编程语言之一。虽然两者看起来很自然地在一起“工作”,但是要知道,Redis 其实并...【详细内容】
2022-06-17  Tags: redis  点击:(10)  评论:(0)  加入收藏
一、什么是分布式锁不同的进程需要以互斥的方式来访问共享资源,这里实现互斥就是分布式锁。简单来说就是:同一时间只有一个客户端对共享资源操作。举个实际例子,抢购茅台,如果不...【详细内容】
2022-06-17  Tags: redis  点击:(10)  评论:(0)  加入收藏
Redis 作为最受欢迎的 NoSQL 数据库之一,具备高性能、高可用性、高扩展性等特点,在各互联网业务中使用广泛。目前业界针对 Redis 的性能优化主要针是配置项优化以及使用方式的...【详细内容】
2022-06-01  Tags: redis  点击:(18)  评论:(0)  加入收藏
话不多说,发车发车! 提纲为什么要有哨兵机制?在 Redis 的主从架构中,由于主从模式是读写分离的,如果主节点(master)挂了,那么将没有主节点来服务客户端的写操作请求,也没有主节点给从...【详细内容】
2022-05-20  Tags: redis  点击:(35)  评论:(0)  加入收藏
有一次去面试服务器端岗位,面试官问我有一个连接过来,你该怎么编程处理它。我答道:“主线程收到请求后,创建一个子线程处理。” 面试官接着问,那如果有一千个连接同时来呢?我说“...【详细内容】
2022-05-11  Tags: redis  点击:(50)  评论:(0)  加入收藏
承接上文Redis底层字符串编码设计思想简介ziplist数据结构 内存会一次性开辟一块大的连续的空间,来存放ziplist。 • zlbytes32bit内存空间,表示ziplist占用的字节总数 &b...【详细内容】
2022-05-09  Tags: redis  点击:(36)  评论:(0)  加入收藏
承接上文深入redis源码,了解数据结构设计思想本地调试redis源码启动redis源码mac下载C语言编译器CLion,拉取redis源码并导入CLion 编译redis源码并启动 编译成功之后,在src目录...【详细内容】
2022-05-09  Tags: redis  点击:(28)  评论:(0)  加入收藏
Redis内存碎片处理不知道我们在执行删除操作时有没有注意过这样一个现象,删除一些bigkey后内存分配器分配的容量并没有减少,实际容量减少了,这是为什么呢?演示如下模拟bigkey删...【详细内容】
2022-05-09  Tags: redis  点击:(33)  评论:(0)  加入收藏
现象:Springboot 接入Redis后发现隔一段时间连接会超时 command timed out。org.springframework.dao.QueryTimeoutException: Redis command timed out; nested exception i...【详细内容】
2022-05-06  Tags: redis  点击:(136)  评论:(0)  加入收藏
▌简易百科推荐
在电商、支付等领域,往往会有这样的场景,用户下单后放弃支付了,那这笔订单会在指定的时间段后进行关闭操作,细心的你一定发现了像某宝、某东都有这样的逻辑,而且时间很准确,误差在...【详细内容】
2022-06-21  海椰人  博客园  Tags:redis   点击:(0)  评论:(0)  加入收藏
Redis 是最流行的 NoSQL 数据库是解决方案之一,而 Java 是世界上最流行(注意,我没有说“最好”)的编程语言之一。虽然两者看起来很自然地在一起“工作”,但是要知道,Redis 其实并...【详细内容】
2022-06-17  蜗牛学技术    Tags: Redisson   点击:(10)  评论:(0)  加入收藏
一、什么是分布式锁不同的进程需要以互斥的方式来访问共享资源,这里实现互斥就是分布式锁。简单来说就是:同一时间只有一个客户端对共享资源操作。举个实际例子,抢购茅台,如果不...【详细内容】
2022-06-17  用Java可可    Tags:分布式锁   点击:(10)  评论:(0)  加入收藏
Redis 作为最受欢迎的 NoSQL 数据库之一,具备高性能、高可用性、高扩展性等特点,在各互联网业务中使用广泛。目前业界针对 Redis 的性能优化主要针是配置项优化以及使用方式的...【详细内容】
2022-06-01  linux技术栈    Tags:Redis性能   点击:(18)  评论:(0)  加入收藏
话不多说,发车发车! 提纲为什么要有哨兵机制?在 Redis 的主从架构中,由于主从模式是读写分离的,如果主节点(master)挂了,那么将没有主节点来服务客户端的写操作请求,也没有主节点给从...【详细内容】
2022-05-20  IT互联网新资讯  微信公众号  Tags:Redis   点击:(35)  评论:(0)  加入收藏
有一次去面试服务器端岗位,面试官问我有一个连接过来,你该怎么编程处理它。我答道:“主线程收到请求后,创建一个子线程处理。” 面试官接着问,那如果有一千个连接同时来呢?我说“...【详细内容】
2022-05-11  开心玩技术    Tags:Redis   点击:(50)  评论:(0)  加入收藏
承接上文Redis底层字符串编码设计思想简介ziplist数据结构 内存会一次性开辟一块大的连续的空间,来存放ziplist。 • zlbytes32bit内存空间,表示ziplist占用的字节总数 &b...【详细内容】
2022-05-09  平凡人笔记    Tags:Redis   点击:(36)  评论:(0)  加入收藏
承接上文深入redis源码,了解数据结构设计思想本地调试redis源码启动redis源码mac下载C语言编译器CLion,拉取redis源码并导入CLion 编译redis源码并启动 编译成功之后,在src目录...【详细内容】
2022-05-09  平凡人笔记    Tags:Redis   点击:(28)  评论:(0)  加入收藏
Redis内存碎片处理不知道我们在执行删除操作时有没有注意过这样一个现象,删除一些bigkey后内存分配器分配的容量并没有减少,实际容量减少了,这是为什么呢?演示如下模拟bigkey删...【详细内容】
2022-05-09  Java面试365    Tags:Redis   点击:(33)  评论:(0)  加入收藏
故障生产环境zabbix突然告警,redis主从服务器的CPU使用率过高。通过堡垒机连接生产服务器查看具体情况。发现占用CPU较高的是redis进程。遂进一步查看redis实例的日志,发现进...【详细内容】
2022-04-27  BlueCore    Tags:Redis   点击:(53)  评论:(0)  加入收藏
站内最新
站内热门
站内头条