利用Redis的setex以及订阅发布功能实现逾期订单的状态修改

    科技2025-05-13  7

    文章目录

    场景描述修改redis.conf配置,以拿到发布的key继承事件监听器,重写onMessage方法编写配置类,注入Bean测试结果存在缺陷

    场景描述

    电商平台,客户下单未支付,会有锁库存的操作,支付有效时间为15min,15分钟之后订单失效,释放库存,修改订单状态。如何实现?

    默认已连接redis,并在springboot引入依赖

    修改redis.conf配置,以拿到发布的key

    继承事件监听器,重写onMessage方法

    public class KeyExpiredListener extends KeyExpirationEventMessageListener { private static final Logger LOGGER = LoggerFactory.getLogger(KeyExpiredListener.class); public KeyExpiredListener(RedisMessageListenerContainer listenerContainer) { super(listenerContainer); } @Override public void onMessage(Message message, byte[] pattern) { String channel = new String(message.getChannel(),StandardCharsets.UTF_8); String key = new String(message.getBody(),StandardCharsets.UTF_8); String patternStr = new String(message.getBody(),StandardCharsets.UTF_8); LOGGER.info("key失效:channel:{},key:{},patternStr:{}",channel,key,patternStr); // 取到逾期支付订单的id if (!StringUtils.isEmpty(key) && key.startsWith("orderId:")){ String[] split = key.split(":"); Long orderId = Long.parseLong(split[1]); // TODO 进行更改状态的操作 } } }

    编写配置类,注入Bean

    @Configuration public class RedisConfiguraion { @Autowired private RedisConnectionFactory redisConnectionFactory; @Bean public RedisMessageListenerContainer redisMessageListenerContainer(){ RedisMessageListenerContainer redisMessageListenerContainer = new RedisMessageListenerContainer(); redisMessageListenerContainer.setConnectionFactory(redisConnectionFactory); return redisMessageListenerContainer; } @Bean public KeyExpiredListener keyExpiredListener(){ return new KeyExpiredListener(redisMessageListenerContainer()); } @Bean // @0表示只监听0号库的失效key,*表示监听所有 public PatternTopic patternTopic(){ return new PatternTopic("__keyevent@0__:expired"); } }

    测试结果

    存在缺陷

    redis的pus/sub不管有没有收到信息,都只发一次!存在网络抖动,发生异常等,意味着可能存在监听丢失,逾期订单不取消。redis-key单线程,同一时间大量失效,可能存在延迟。如果orderservice服务是集群配置,所有客户端都会收到key失效的event;此时加上redis分布式锁处理。
    Processed: 0.009, SQL: 8