redis过期监听

  redis 是一个高性能的 KV 数据库,除了用作缓存以外,其实还提供了过期监听的功能在 redis.conf 中,配置 notify-keyspace-events Ex 即可开启此功能。
然后在代码中继承 KeyspaceEventMessageListener,实现 onMessage 就可以监听过期的数据量

public abstract class KeyspaceEventMessageListener implements MessageListener, InitializingBean, DisposableBean {
		private static final Topic TOPIC_ALL_KEYEVENTS = new PatternTopic("__keyevent@*");
        //...省略部分代码
		public void init() {
				if (StringUtils.hasText(keyspaceNotificationsConfigParameter)) {
					RedisConnection connection = listenerContainer.getConnectionFactory().getConnection();
					try {
						Properties config = connection.getConfig("notify-keyspace-events");
						if (!StringUtils.hasText(config.getProperty("notify-keyspace-events"))) {
						  connection.setConfig("notify-keyspace-events", keyspaceNotificationsConfigParameter);
						}
					} finally {
					  connection.close();
					}
				}
				doRegister(listenerContainer);
		}
		protected void doRegister(RedisMessageListenerContainer container) {
		  listenerContainer.addMessageListener(this, TOPIC_ALL_KEYEVENTS);
		}
		//...省略部分代码
		@Override
		public void afterPropertiesSet() throws Exception {
			init();
		}
}

  通过以上源码,我们可以发现,其本质也是注册一个 listener,利用 redis 的发布订阅,当 key 过期时,发布过期消息(key)到 Channel :keyevent@*:expired 中。
在实际的业务中,我们可以将订单的过期时间设置比如 30 分钟,然后放入到 redis。30 分钟之后,就可以消费这个 key,然后做一些业务上的后置动作,比如检查用户是否支付。

优点:由于 redis 的高性能,所以我们在设置 key,或者消费 key 时,速度上是可以保证的。
缺点:由于 redis 的 key 过期策略原因,当一个 key 过期时,redis 无法保证立刻将其删除,自然我们的监听事件也无法第一时间消费到这个 key,所以会存在一定的延迟。
另外,在 redis5.0 之前,订阅发布中的消息并没有被持久化,自然也没有所谓的确认机制。所以一旦消费消息的过程中我们的客户端发生了宕机,这条消息就彻底丢失了。
总结:redis 的过期订阅相比于其他方案没有太大的优势,在实际生产环境中,用得相对较少
posted on 2024-08-29 16:27  坐在云上飘  阅读(221)  评论(0)    收藏  举报