美文网首页框架建设收集
基于Spring Boot实现Redis Key过期失效处理

基于Spring Boot实现Redis Key过期失效处理

作者: bearPotMan | 来源:发表于2019-07-26 19:48 被阅读196次

    1 场景描述

    用户下单,默认保留 15分钟 的支付时间,在规定的时间内用户未完成支付即设置订单状态为 已取消

    2 前言

    不管你用没用过 redis,它有一个功能你一定会觉得很奈斯,那就是 key 的过期失效机制,请看 Redis官方解释,简单来讲就是 key 超时过期后会自动删除。这里我们就使用 redis 来实现上面描述的这种场景!

    3 环境

    JDK 1.8
    Spring Boot 2.1.6

    4 代码实现

    4.1 项目创建

    • 创建 Spring Initializer 项目
    • 添加依赖
      spring-boot-starter-data-redis(主要依赖)
      spring-boot-starter-web(只为后面编写接口做辅助)
      lombok(只为减少代码量)
      完整依赖:
    <dependencies>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>
    
    • 配置 application.yml
    spring:
      redis:
        host: 127.0.0.1
        port: 6379
    

    4.2 redis监听器容器配置类

    @Configuration
    public class RedisListenerConfig {
        @Bean
        public RedisMessageListenerContainer container(RedisConnectionFactory connectionFactory) {
            RedisMessageListenerContainer container = new RedisMessageListenerContainer();
            container.setConnectionFactory(connectionFactory);
            return container;
        }
    }
    

    4.3 key 过期监听器

    @Component
    @Slf4j
    public class RedisKeyExpirationListener extends KeyExpirationEventMessageListener {
    
        public RedisKeyExpirationListener(RedisMessageListenerContainer listenerContainer) {
            super(listenerContainer);
        }
    
        @Override
        public void onMessage(Message message, byte[] pattern) {
            // 注意:我们只能获取到失效的 key 而获取不到 value,
            // 所以在设计 key 的时候可以考虑把 value 一并放到 key,然后根据规则取出 value
            String key = new String(message.getBody());
            log.info("key:{}", key);
            // message.toString()也可以获取失效的key
            String expiredKey = message.toString();
            log.info("expiredKey:{}", expiredKey);
            //如果是 order- 开头的key,将订单状态设置为 已取消
            if(expiredKey.startsWith("order-")){
                log.info("订单已过期:查询数据库对应记录是否已支付");
                // TODO
            }
        }
    }
    

    4.4 测试

    • 编写接口测试
    @RestController
    public class WebController {
    
        @Autowired
        private StringRedisTemplate redisTemplate;
    
        @PostMapping("/order")
        public String order() {
            // 订单号
            String orderNo = UUID.randomUUID().toString().replaceAll("-", "");
            // 假设 redis key 设置过期时间:30s
            redisTemplate.opsForValue().set(String.format("order-%s", orderNo),
                    orderNo, 30, TimeUnit.SECONDS);
            return orderNo;
        }
    }
    

    启动项目,请求接口测试,控制台打印日志:

    key:order-5b84dacd0a014dbbaa97cf26852f715b
    expiredKey:order-5b84dacd0a014dbbaa97cf26852f715b
    订单已过期:查询数据库对应记录是否已支付
    

    如上所述,我们利用 redis 实现了这个功能。
    当然实现这个功能不止这一种方法,各位朋友可以尽显神通!

    2019-07-29更新
    更新的原因很简单:多写了一点内容,所以删除了,免得误导他人!

    相关文章

      网友评论

        本文标题:基于Spring Boot实现Redis Key过期失效处理

        本文链接:https://www.haomeiwen.com/subject/fbxlrctx.html