SpringBoot监听redis键过期事件,实现订单超时关闭

本文介绍了如何在SpringBoot中利用Redis的键过期事件来实现订单超时关闭。传统方法依赖定时任务,而通过监听Redis事件可以更高效地处理超时订单。然而,Redis的事件通知策略目前不保证消息可靠性。文章详细讲解了配置Redis的键空间通知、开启事件监听,并提供了相关的SpringBoot监听器配置示例。
摘要由CSDN通过智能技术生成

SpringBoot监听redis键过期事件,实现订单超时关闭

场景

订单超时关闭,客户下单时未支付,超过一段时间会自动将订单修改为已关闭,不允许再次支付。类似的场景还有很多,只要用到有过期概念的都可以设计成该做法。

通常做法

  1. 通过定时任务每隔一段时间检查是否有超时订单,修改订单的状态,释放库存等等。
  2. 缺点:后台定时任务运行频繁,涉及订单操作业务比较复杂,增加服务器压力

思路

  1. 单机部署可以使用java8里面的DelayQueue延时队列,对超时的订单执行取消操作,同时缺点也存在,比如服务器宕机,那保存在内存的订单延时队列就被清空,对业务影响也比较大,建议和定时器结合使用。
  2. 使用redis存储过期键,当存储的键值过期时,发出事件通知,通知到程序,执行取消订单操作,不过同时也有宕机风险。因为 Redis 目前的订阅与发布功能采取的是发送即忘(fire and forget)策略, 所以如果你的程序需要可靠事件通知(reliable notification of events), 那么目前的键空间通知可能并不适合你:当订阅事件的客户端断线时, 它会丢失所有在断线期间分发给它的事件。并不能确保消息送达。未来有计划允许更可靠的事件传递,但可能这将在更一般的层面上解决,或者为Pub / Sub本身带来可靠性,或者允许Lua脚本拦截Pub
可以使用 Spring Data Redis 提供的 @EnableRedisRepositories 注解,同时实现 RedisKeyExpirationListener 接口,并在 @Configuration 类添加监听器配置。 以下是代码片段示例: @Configuration @EnableRedisRepositories public class RedisConfig { @Bean public RedisTemplate<String, Object> redisTemplate() { RedisTemplate<String, Object> template = new RedisTemplate<>(); template.setConnectionFactory(jedisConnectionFactory()); return template; } @Bean public JedisConnectionFactory jedisConnectionFactory() { return new JedisConnectionFactory(); } @Bean public RedisMessageListenerContainer redisContainer() { RedisMessageListenerContainer container = new RedisMessageListenerContainer(); container.setConnectionFactory(jedisConnectionFactory()); return container; } @Bean RedisKeyExpirationListener keyExpirationListener() { return new RedisKeyExpirationListener(); } @Bean MessageListenerAdapter listenerAdapter(RedisKeyExpirationListener keyExpirationListener) { return new MessageListenerAdapter(keyExpirationListener); } @Bean RedisMessageListenerContainer keyExpirationContainer(RedisKeyExpirationListener keyExpirationListener, MessageListenerAdapter listenerAdapter) { RedisMessageListenerContainer container = new RedisMessageListenerContainer(); container.setConnectionFactory(jedisConnectionFactory()); container.addMessageListener(listenerAdapter, new PatternTopic("__keyevent@*:expired")); return container; } private static class RedisKeyExpirationListener implements MessageListener { @Override public void onMessage(Message message, byte[] pattern) { String expiredKey = message.toString(); // 处理过期key逻辑 } } } 这里我们定义了一个 RedisContainer 和一个 RedisKeyExpirationListener,然后将 RedisKeyExpirationListener 获取到的过期 key 进行处理。ListenAdapter 和 keyExpirationContainer 主要是为了配置监听器,其"__keyevent@*:expired"用来监听所有 Redis 发生的 key 过期事件
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值