• springboot利用redis过期事件处理过期订单


    前言

    在开发中我们经常会遇到这样的业务需求,某一条数据需要在xxx时间后处理,比如说未支付的订单,30分钟后过期。能够实现这一功能的技术有很多,但需要你根据系统的大小、业务的量的大小以及公司给到该项目的资源而决定。

    比如说这是一个大商城,开始之初就已经部署了rabbitmq,那毫无疑问可以使用延时队列实现这一功能。如果说没有提供mq,一般情况下我们就定时轮询订单表了,这是非常最简单的一种实现方式。如果说你怕数据库压力大,那不妨可以选择redis。这篇文章介绍的就是如何利用redis处理过期事件。

    实现

    1.开启配置

    打开redis.conf,开启如下配置

    notify-keyspace-events Ex
    
    • 1

    这是为了使 Redis Key 过期事件能够被监听 ,需要启用 Redis 的键空间通知功能

    2.创建监听器类

    import lombok.extern.slf4j.Slf4j;
    import org.springframework.data.redis.connection.Message;
    import org.springframework.data.redis.connection.MessageListener;
    
    @Slf4j
    public class RedisKeyExpiredListener implements MessageListener {
        @Override
        public void onMessage(Message message, byte[] pattern) {
            String expiredKey = message.toString();
            log.info("获取数据:"+expiredKey);
            if (expiredKey.startsWith("order:")) {
                // 一般来说,我们会这样设置过期订单的key:"order:255 "
                String orderId = expiredKey.split(":")[1];
                log.info("订单ID:"+orderId);
                // 处理实际业务
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    3.将监听器注册为 Bean

    import com.gpt.dc.web.listener.RedisKeyExpiredListener;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.data.redis.connection.RedisConnectionFactory;
    import org.springframework.data.redis.listener.PatternTopic;
    import org.springframework.data.redis.listener.RedisMessageListenerContainer;
    
    @Configuration
    public class RedisConfig {
        @Bean
        public RedisMessageListenerContainer redisMessageListenerContainer(RedisConnectionFactory connectionFactory,
                                                                           RedisKeyExpiredListener listener) {
            RedisMessageListenerContainer container = new RedisMessageListenerContainer();
            container.setConnectionFactory(connectionFactory);
    
            // 配置监听的 Redis Key 过期事件的频道
            container.addMessageListener(listener, new PatternTopic("__keyevent@*__:expired"));
    
            return container;
        }
    
        @Bean
        public RedisKeyExpiredListener redisKeyExpiredListener() {
            return new RedisKeyExpiredListener();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    我们在配置类 RedisConfig 中将监听器注册为 Bean,并通过 RedisMessageListenerContainer 配置监听容器。我们使用 addMessageListener() 方法来添加监听器,并指定要监听的 Redis Key 过期事件的频道(__keyevent@*__:expired

    接下来测试一下

    @GetMapping("save")
    public void saveOrder(Long id){
        RedisUtil.set("order:"+id, id.toString(), 10L);
    }
    
    • 1
    • 2
    • 3
    • 4

    10后过期,RedisKeyExpiredListener中的onMessage方法会自动监听,并在控制台上打印如下信息

    c.g.d.w.l.RedisKeyExpiredListener:17   redisMessageListenerContainer-1                    获取数据:order:2
    c.g.d.w.l.RedisKeyExpiredListener:20   redisMessageListenerContainer-1                    订单ID:2
    
    • 1
    • 2
  • 相关阅读:
    Asterisk Ubuntu 安装
    linux系统下,mysql增加用户
    【Java实验五】继承与多态
    复习mysql中的事务
    将任何网页变成桌面应用,全平台支持 | 开源日报 No.184
    简明docker安装
    测试用例设计方法六脉神剑——第二剑:招式组合,因果判定出世
    Java学习----前端2
    大机中的asm example
    (附源码)mysql小程序+springboot流浪动物保护平台 毕业设计 161154
  • 原文地址:https://blog.csdn.net/gzmyh/article/details/134440268