基于Redis实现订单倒计时⾃动关闭——Java
1.场景:
电商系统或者购票系统都必须具备订单功能,⽣成订单后⼀段时间不⽀付订单会⾃动关闭。最简单的想法是设置定时任务轮询, 但是每个订单的创建时间不⼀样,定时任务的规则⽆法设定,如果将定时任务执⾏的间隔设置的过短,太影响效率。还有⼀种想法,在⽤户进⼊订单界⾯的时候,判断时间执⾏相关操作。⽅式可能有很多,在这⾥介绍⼀种监听Redis键值对过期时间来实现订单⾃动关闭。
2.思路:
在⽣成订单时,向Redis中增加⼀个KV键值对,K为订单号,或者订单id,保证通过K能定位到数据库中的某个订单即可,V可为任意值(后边会解释为什么V可为任意值)。
假设,⽣成订单时向Redis中存放K为订单号,V也为订单号的键值对,并设置过期时间为30分装,如果该键值对在30分钟过期后能够发送给程序⼀个通知,或者执⾏⼀个⽅法,那么即可解决订单关闭问题。
实现:通过监听Redis提供的过期队列来实现,监听过期队列后,如果Redis中某⼀个KV过期了,那么将向监听者发送消息,监听者可以获取到该键值对的K,注意,是获取不到V的,因为已经过期了,这就是上⾯所提到的,为什么要保证能通过K来定位到订单,⽽V为任意值即可。拿到K后,通过K定位订单,捐赠支出
并判断其状态,如果是未⽀付,更新为关闭,或者取消状态即可。
3.实现:
1.项⽬为SSM框架基础架构。
2.使⽤SpringDataRedis来操作Redis(SDR)。
3.创建⼀个监听者类,实现SDR提供的监听者接⼝。
public class TopicMessageListener implements MessageListener {
@Override
public void onMessage(Message message, byte[] bytes) {
byte[] body = Body();// 请使⽤valueSerializer
byte[] channel = Channel();
//设置监听频道
String topic = new String(channel);
//key
String itemValue = new String(body);
System.out.println("频道topic:"+topic);
System.out.println("过期的键值对的K:"+itemValue);
}
}
4.在spring配置⽂件中,增加监听者的配置
<!-- redis 连接⼯⼚ -->
sunny side up>绑带
<bean id="redisConnectionFactory"
class="org.tion.jedis.JedisConnectionFactory"
p:port="6379" p:host-name="127.0.0.1" p:password=""/>
<!-- ⽤来格式化 KV 的类 -->
<bean id="stringSer" class="org.dis.rializer.StringRedisSerializer" />
kg是什么单位<bean id="jdkSer" class="org.dis.rializer.JdkSerializationRedisSerializer" />
<!-- Spring操作redis的模板类 -->
<bean id="redisTemplate" class="org.RedisTemplate"
p:connectionFactory-ref="redisConnectionFactory">
<property name="keySerializer" ref="stringSer" />
<property name="valueSerializer" ref="jdkSer" />
</bean>
<!-- 将监听者类放⼊Spring容器 -->
<bean id="messageListener" class="org.dis.listener.adapter.MessageListenerAdapter">
<constructor-arg>
<bean class="utils.TopicMessageListener"/>
</constructor-arg>
</bean>
<!-- 配置监听者容器 -->
<bean id="redisContainer" class="org.dis.listener.RedisMessageListenerContainer">
天津人力资源培训<property name="connectionFactory" ref="redisConnectionFactory"/>
<property name="messageListeners">
<map>we are not alone
<entry key-ref="messageListener">
<bean class="org.dis.listener.ChannelTopic">
<constructor-arg value="__keyevent@0__:expired"/>
</bean>
</entry>
</map>
</property>
</bean>
5.都是⼀些使⽤SDR的常⽤配置,简单解释⼀下如下配置
vj是什么
6.这个配置,配置的是监听的频道,格式为固定,Redis有16个库,配置中0代表监听第0个库,如果要监听所有库,可将0改为*,星号,如果监听其他库,将0改为库的编号即可0-15。keyevent代表监听的事件类型,expired表⽰,监听的时间为过期事件,也就是当第0个库中如果有KV过期,那么,监听者类将接受到消息。注意,配置中有两处出现了下划线,每⼀处下划线均有两个下划线组成,⼀定要注意 这是⼀个下划线 _ 这是两个下划线 __ 。
7.修改Redis配置⽂件,开启过期通知功能人教英语
dramatic irony
标记1处原来是被注释掉的,打开注释。
标记2处原来是没有注解的,将其注释掉。这两处为开始Redis的过期通知功能,保证跟图中的注释⼀致即可。
the world as i e it还有要保证程序能够连接上Redis,该配置中0.0.0.0表⽰任意ip都可连接Redis。
8.那么到这⾥其实重要的配置已经完成,可以启动项⽬,进⾏测试。打开Redis客户端,存放KV并设置过期时间,如t testKey testValue Ex 5。存放⼀个键值对,过期时间为5秒,那么5秒后监听者类就会收到消息。
9.已经可以成功的监听到过期频道,并且能够接受到过期消息,实际业务根据需求拓展即可。