当前位置:网站首页> 利用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分钟自动取消内容请搜索软件开发网以前的文章或继续浏览下面的相关文章希望大家以后多多支持软件开发网!
边栏推荐
- [high concurrency] deeply analyze the callable interface
- Centos8 PostgreSQL initialization error: initdb: error: invalid locale settings; check LANG and LC_* environment
- I want to buy fixed income + products, but I don't know what its main investment is. Does anyone know?
- 机械硬盘和ssd固态硬盘的原理对比分析
- 关于快速幂
- NFT双币质押流动性挖矿dapp合约定制
- 数学建模经验分享:国赛美赛对比/选题参考/常用技巧
- Admixture usage document Cookbook
- Beginner level Luogu 1 [sequence structure] problem list solution
- 避孕套巨头过去两年销量下降40% ,下降原因是什么?
猜你喜欢

The latest development course of grain college in 2022: 8 - foreground login function

#27ES6的数值扩展
![[high concurrency] deeply analyze the callable interface](/img/24/33c3011752c8f04937ad68d85d4ece.jpg)
[high concurrency] deeply analyze the callable interface

Problems encountered in vs compilation
![Luogu_ P1008 [noip1998 popularization group] triple strike_ enumeration](/img/9f/64b0b83211bd1c615f2db9273bb905.png)
Luogu_ P1008 [noip1998 popularization group] triple strike_ enumeration

PSS: you are only two convolution layers away from the NMS free+ point | 2021 paper

Eolink 推出面向中小企业及初创企业支持计划,为企业赋能!

开源二三事|ShardingSphere 与 Database Mesh 之间不得不说的那些事

HTTP Caching Protocol practice

Teach you how to realize pynq-z2 bar code recognition
随机推荐
专家:让你低分上好校的都是诈骗
Expert: those who let you go to a good school with a low score are all Scams
SQL injection principle
Design of spread spectrum communication system based on FPGA (with main code)
Design of direct spread spectrum communication system based on FPGA (with main code)
Markdown syntax
Talk about redis transactions
数学建模经验分享:国赛美赛对比/选题参考/常用技巧
【kotlin】第二天
洛谷_P1003 [NOIP2011 提高组] 铺地毯_暴力枚举
SQL parsing practice of Pisa proxy
【170】PostgreSQL 10字段类型从字符串修改成整型,报错column cannot be cast automatically to type integer
Does polardb-x currently not support self-made database service Das?
Problems encountered in vs compilation
Let's talk about the process of ES Indexing Documents
2022年最新《谷粒学院开发教程》:8 - 前台登录功能
SQL parsing practice of Pisa proxy
Cesium 使用MediaStreamRecorder 或者MediaRecorder录屏并下载视频,以及开启摄像头录像。【转】
[issue 17] golang's one-year experience in developing Meitu
Redis CacheClient