关于https:生成订单后一段时间不支付订单会自动关闭的功能该如何实现

48次阅读

共计 2509 个字符,预计需要花费 7 分钟才能阅读完成。

业务场景


咱们以订单性能为例阐明下:生成订单后一段时间不领取订单会主动敞开。最简略的想法是设置定时工作轮询,然而每个订单的创立工夫不一样,定时工作的规定无奈设定,如果将定时工作执行的距离设置的过短,太影响效率。还有一种想法,在用户进入订单界面的时候,判断工夫执行相干操作。形式可能有很多,在这里介绍一种监听 Redis 键值对过期工夫来实现订单主动敞开

实现思路


在生成订单时,向 Redis 中减少一个 KV 键值对,K 为订单号,保障通过 K 能定位到数据库中的某个订单即可,V 可为任意值。假如,生成订单时向 Redis 中寄存 K 为订单号,V 也为订单号的键值对,并设置过期工夫为 30 分钟,如果该键值对在 30 分钟过期后可能发送给程序一个告诉,或者执行一个办法,那么即可解决订单敞开问题。实现:通过监听 Redis 提供的过期队列来实现,监听过期队列后,如果 Redis 中某一个 KV 键值对过期了,那么将向监听者发送音讯,监听者能够获取到该键值对的 K,留神,是获取不到 V 的,因为曾经过期了,这就是下面所提到的,为什么要保障能通过 K 来定位到订单,而 V 为任意值即可。拿到 K 后,通过 K 定位订单,并判断其状态,如果是未领取,更新为敞开,或者勾销状态即可。

开启 Redis key 过期揭示


批改 redis 相干事件配置。找到 redis 配置文件 redis.conf,查看 notify-keyspace-events 配置项,如果没有,增加 notify-keyspace-events Ex,如果有值,则追加 Ex,相干参数阐明如下:

  • K:keyspace 事件,事件以 keyspace@ 为前缀进行公布
  • E:keyevent 事件,事件以 keyevent@ 为前缀进行公布
  • g:一般性的,非特定类型的命令,比方 del,expire,rename 等
  • $:字符串特定命令
  • l:列表特定命令
  • s:汇合特定命令
  • h:哈希特定命令
  • z:有序汇合特定命令
  • x:过期事件,当某个键过期并删除时会产生该事件
  • e:驱赶事件,当某个键因 maxmemore 策略而被删除时,产生该事件
  • A:g$lshzxe 的别名,因而”AKE”意味着所有事件

引入依赖


在 pom.xml 中增加 org.springframework.boot:spring-boot-starter-data-redis 依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
复制代码 

相干配置


定义配置 RedisListenerConfig 实现监听 Redis key 过期工夫

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.RedisMessageListenerContainer;

@Configuration
public class RedisListenerConfig {

    @Bean
    RedisMessageListenerContainer container(RedisConnectionFactory connectionFactory) {RedisMessageListenerContainer container = new RedisMessageListenerContainer();
        container.setConnectionFactory(connectionFactory);
        return container;
    }
}
复制代码 

定义监听器 RedisKeyExpirationListener,实现 KeyExpirationEventMessageListener 接口,查看源码发现,该接口监听所有 db 的过期事件 keyevent@*:expired”

import org.springframework.data.redis.connection.Message;
import org.springframework.data.redis.listener.KeyExpirationEventMessageListener;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
import org.springframework.stereotype.Component;

/**
 * 监听所有 db 的过期事件__keyevent@*__:expired"
 */
@Component
public class RedisKeyExpirationListener extends KeyExpirationEventMessageListener {public RedisKeyExpirationListener(RedisMessageListenerContainer listenerContainer) {super(listenerContainer);
    }

    /**
     * 针对 redis 数据生效事件,进行数据处理
     * @param message
     * @param pattern
     */
    @Override
    public void onMessage(Message message, byte[] pattern) {

        // 获取到生效的 key,进行勾销订单业务解决
        String expiredKey = message.toString();
        System.out.println(expiredKey);
    }
}

参考:《2020 最新 Java 根底精讲视频教程和学习路线!》

链接:https://juejin.cn/post/691909…

正文完
 0