我们在网上购物的时候,经常会遇到未支付,然后有个倒计时的情况,倒计时完了还未付款就取消订单的情况。
那么这个这个功能要怎么实现呢?
需求很简单,反正就是下单操作后,一段时间,进行另外的操作。想了一下好像Redis的广播好像也不错。
那我们来操作一下:
方法一:用Redis的失效广播
Redis是有两种事件通知方式的,分别是:键过期事件(keyspace notification)和键空间通知(pub/sub notification)。
键过期事件 就是键过期的时候,Redis会生成一个过期事件,发布给订阅者。这个键过期事件是 Redis 默认会发送的事件之一。通知的发送是基于订阅-发布模式(Pub/Sub),Redis 会将键过期事件发到 __keyevent@*__:expired 频道,这个 *是指定的数据库号。
键空间通知,键空间是Redis里面键的集合,可以监视键的创建、修改和删除等事件。(默认是不开的,因为会影响性能)
简单点说就是键过期事件主要关注键过期这一具体事件,而键空间通知则提供了更广泛的事件范围,包括键的创建、修改、删除等事件。
那我们这个需求很简单了嘛,直接监听默认的过期事件就好了。
1. 注册一个监听器
SpringBoot项目可以通过 实现 MessageListener 接口 来监听Redis 键过期事件。需要重写onMessage方法。
这个方法就是你的业务逻辑。我这里就先简单打印一下过期的Key
(注意:这里是拿不到这个Key对应的Value的)
@Component
public class RedisKeyListener implements MessageListener {
@Override
public void onMessage(Message message, byte[] bytes) {
String mess = message.toString();
String messToString = Arrays.toString(message.getBody());
System.out.println("onMessage...:" + mess);
System.out.println("onMessage...:" + messToString);
}
}
2.注册一个监听容器,配置监听频道
随便在什么配置类中注册成Bean就好,你可以新建一个RedisKeyListenerConfig(规范点是要这样),我由于做演示偷懒一下,就在RedisConfig里面写了。
@Configuration
public class RedisConfig {
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
RedisTemplate<String, Object> template = new RedisTemplate<>();
template.setConnectionFactory(factory);
return template;
}
@Bean
public RedisMessageListenerContainer redisMessageListenerContainer(RedisConnectionFactory connectionFactory, RedisKeyListener redisKeyListener) {
RedisMessageListenerContainer container = new RedisMessageListenerContainer();
container.setConnectionFactory(connectionFactory);
container.addMessageListener(redisKeyListener, new PatternTopic("__keyevent@*__:expired"));
return container;
}
}
RedisTemplate就不说了。
RedisMessageListenerContainer 是 Spring Data Redis包下的一个组件,用来管理 Redis 消息的监听、处理什么的。 这个容器 通过addMessageListener()方法注册消息监听器。
我们这里用的监听器就是第1步写的 RedisKeyListener,这个方法的第二个参数是指定要监听的频道。
__keyevent@*__:expired 表示监听所有数据库的键过期事件。你也可以改改,比如:
__keyevent@0__:expired 就表示 监听db0 (如下图)
到这里就完事了,直接run。到Redis中新增一个key。
设置过期时间为3秒
等待三秒,成功打印。
这样一个简单的键过期事件监听就实现了。
那有了key,就等于有了orderId 那判断订单状态并取消订单就是随随便便的事情啦。
先到这里 后面有时间了补充一下用MQ的方案。