当前位置:网站首页> 利用Redis实现订单30分钟自动取消
利用Redis实现订单30分钟自动取消
2022-06-27 15:30:00 【1024问】
业务场景
实现思路
开启 Redis key 过期提醒
引入依赖
相关配置
redis 过期监听真的好么?
实现关闭订单的方法
业务场景我们以订单功能为例说明下:
生成订单后一段时间不支付订单会自动关闭。最简单的想法是设置定时任务轮询,但是每个订单的创建时间不一样,定时任务的规则无法设定,如果将定时任务执行的间隔设置的过短,太影响效率。
还有一种想法,在用户进入订单界面的时候,判断时间执行相关操作。方式可能有很多,在这里介绍一种监听 Redis 键值对过期时间来实现订单自动关闭。
实现思路在生成订单时,向 Redis 中增加一个 KV 键值对,K 为订单号,保证通过 K 能定位到数据库中的某个订单即可,V 可为任意值。
假设,生成订单时向 Redis 中存放 K 为订单号,V 也为订单号的键值对,并设置过期时间为 30 分钟,如果该键值对在 30 分钟过期后能够发送给程序一个通知,或者执行一个方法,那么即可解决订单关闭问题。
实现:通过监听 Redis 提供的过期队列来实现,监听过期队列后,如果 Redis 中某一个 KV 键值对过期了,那么将向监听者发送消息,监听者可以获取到该键值对的 K,注意,是获取不到 V 的,因为已经过期了,这就是上面所提到的,为什么要保证能通过 K 来定位到订单,而 V 为任意值即可。拿到 K 后,通过 K 定位订单,并判断其状态,如果是未支付,更新为关闭,或者取消状态即可。
开启 Redis key 过期提醒修改 redis 相关事件配置。找到 redis 配置文件 redis.conf,查看 notify-keyspace-events 配置项,如果没有,添加 notify-keyspace-events Ex,如果有值,则追加 Ex,相关参数说明如下:
K:keyspace 事件,事件以 [email protected] 为前缀进行发布
E:keyevent 事件,事件以 [email protected] 为前缀进行发布
g:一般性的,非特定类型的命令,比如del,expire,rename等
$:字符串特定命令
l:列表特定命令
s:集合特定命令
h:哈希特定命令
z:有序集合特定命令
x:过期事件,当某个键过期并删除时会产生该事件
e:驱逐事件,当某个键因 maxmemore 策略而被删除时,产生该事件
A:g$lshzxe的别名,因此”AKE”意味着所有事件
引入依赖在 pom.xml 中添加 org.springframework.boot:spring-boot-starter-data-redis 依赖
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId></dependency>相关配置定义配置 RedisListenerConfig 实现监听 Redis key 过期时间
import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.data.redis.connection.RedisConnectionFactory;import org.springframework.data.redis.listener.RedisMessageListenerContainer;@Configurationpublic class RedisListenerConfig { @Bean RedisMessageListenerContainer container(RedisConnectionFactory connectionFactory) { RedisMessageListenerContainer container = new RedisMessageListenerContainer(); container.setConnectionFactory(connectionFactory); return container; }}定义监听器 RedisKeyExpirationListener,实现KeyExpirationEventMessageListener 接口,查看源码发现,该接口监听所有 db 的过期事件 [email protected]*:expired"
import org.springframework.data.redis.connection.Message;import org.springframework.data.redis.listener.KeyExpirationEventMessageListener;import org.springframework.data.redis.listener.RedisMessageListenerContainer;import org.springframework.stereotype.Component;/** * 监听所有db的过期事件[email protected]*__:expired" */@Componentpublic class RedisKeyExpirationListener extends KeyExpirationEventMessageListener { public RedisKeyExpirationListener(RedisMessageListenerContainer listenerContainer) { super(listenerContainer); } /** * 针对 redis 数据失效事件,进行数据处理 * @param message * @param pattern */ @Override public void onMessage(Message message, byte[] pattern) { // 获取到失效的 key,进行取消订单业务处理 String expiredKey = message.toString(); System.out.println(expiredKey); }}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” 的解决方案,不建议使用。
实现关闭订单的方法一般实现的方法有几种:
使用 rocketmq、rabbitmq、pulsar 等消息队列的延时投递功能
使用 redisson 提供的 DelayedQueue
有一些方案虽然广为流传但存在着致命缺陷,不要用来实现延时任务
使用 redis 的过期监听
使用 rabbitmq 的死信队列
使用非持久化的时间轮
到此这篇关于利用Redis实现订单30分钟自动取消的文章就介绍到这了,更多相关Redis订单30分钟自动取消内容请搜索软件开发网以前的文章或继续浏览下面的相关文章希望大家以后多多支持软件开发网!
边栏推荐
- Eolink launched a support program for small and medium-sized enterprises and start-ups to empower enterprises!
- 创建数据库并使用
- HTTP Caching Protocol practice
- 洛谷_P1008 [NOIP1998 普及组] 三连击_枚举
- Use of abortcontroller
- Talk about redis transactions
- Centos8 PostgreSQL initialization error: initdb: error: invalid locale settings; check LANG and LC_* environment
- Interview question: rendering 100000 data solutions
- 一场分销裂变活动,不止是发发朋友圈这么简单!
- 28 object method extension
猜你喜欢
![Luogu_ P1002 [noip2002 popularization group] crossing the river_ dp](/img/80/4edf21e0ac316fe3dd727159621acb.png)
Luogu_ P1002 [noip2002 popularization group] crossing the river_ dp

About tensorflow using GPU acceleration

Teach you how to package and release the mofish Library

Eolink launched a support program for small and medium-sized enterprises and start-ups to empower enterprises!

Vulnerability recurrence ----- 34. Yapi remote command execution vulnerability

PSS: vous n'êtes qu'à deux niveaux du NMS Free + Lifting point | 2021 Paper

What is the London Silver unit

Problems encountered in vs compilation
![[kotlin] the next day](/img/13/9040e72de1243e827045b4572b0cd9.png)
[kotlin] the next day

Keep valid digits; Keep n digits after the decimal point;
随机推荐
【170】PostgreSQL 10字段类型从字符串修改成整型,报错column cannot be cast automatically to type integer
Pychart installation and setup
HTTP Caching Protocol practice
What is the London Silver unit
我想買固收+產品,但是不了解它主要投資哪些方面,有人知道嗎?
About sitemap XML problems
Google Earth Engine(GEE)——Export. image. The difference and mixing of toasset/todrive, correctly export classification sample data to asset assets and references
[kotlin] the next day
Handling methods for NVIDIA deepstream running delay, jamming and crash
Scrapy framework (I): basic use
February 16, 2022 freetsdb compilation and operation
VS编译遇到的问题
Strong, weak, soft and virtual references of ThreadLocal
PSS: vous n'êtes qu'à deux niveaux du NMS Free + Lifting point | 2021 Paper
Creation and use of static library (win10+vs2022
Today, Teng Xu came out with 37k during the interview. It's really a miracle. He showed me his skill
16 -- 删除无效的括号
Design of UART controller based on FPGA (with code)
How is the London Silver point difference calculated
Hyperledger Fabric 2. X custom smart contract