前言
通过开启key过期的事件通知,当key过期时,会发布过期事件;我们定义key过期事件的监听器,当key过期时,就能收到回调通知。但是这个只能是测试或者简单的场景使用,最好不要在生产上使用,尤其是大项目,可能不太靠谱,下面讲一下如果使用
使用场景
消息作为key,将需要延迟的时间设置为key的TTL,当key过期时,在监听器收到通知,达到延迟的效果,不如订单过期通知,订单需要10分钟内支付,过期后需要变更为已取消
配置
需要修改redis.conf配置文件
1
| notify-keyspace-events Ex
|
在配置文件搜索notify-keyspace-events
,默认后面是 “”,两个双引号,删除,改为 Ex即可
使用
java代码,先订阅
1 2 3 4 5 6 7 8
| @Bean public RedisMessageListenerContainer redisMessageListenerContainer(RedisConnectionFactory redisConnectionFactory) { RedisMessageListenerContainer messageListenerContainer = new RedisMessageListenerContainer(); messageListenerContainer.setConnectionFactory(redisConnectionFactory); return messageListenerContainer; }
|
再监听
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| @Component public class RedisKeyExpirationListener extends KeyExpirationEventMessageListener {
public RedisKeyExpirationListener(RedisMessageListenerContainer redisMessageListenerContainer) { super(redisMessageListenerContainer); }
@Override public void onMessage(Message message, byte[] pattern) { String channel = new String(message.getChannel()); String pa = new String(pattern); String expiredKey = message.toString(); System.out.println("监听到过期key:" + expiredKey); } }
|
注意:
1)由于Redis key过期删除是定时+惰性,当key过多时,删除会有延迟,回调通知同样会有延迟。因此性能较低
2)且通知是一次性的,没有ack机制,若收到通知后处理失败,将不再收到通知。需自行保证收到通知后处理成功。
3)通知只能拿到key,拿不到value
4)Redis将数据存储在内存中,如果遇到恶意下单或者刷单的将会给内存带来巨大压力
所有,如果生产上有需求,最好是使用带延迟功能消息中间件(比如pulsar)