Redis实现订单自动过期功能的示例代码

前言

用户下单后,规定XX分钟后自动设置为“已过期”,不能再发起支付。项目类似此类"过期"的需求,笔者提供一种使用Redis的解决思路,结合Redis的订阅、发布和键空间通知机制(Keyspace Notifications)进行实现。

配置redis.confg

notify-keyspace-events选项默认是不启用,改为notify-keyspace-events “Ex”。重启生效,索引位i的库,每当有过期的元素被删除时,向**keyspace@:expired**频道发送通知。
E表示键事件通知,所有通知以__keyevent@__:expired为前缀;
x表示过期事件,每当有过期被删除时发送。

与SpringBoot进行集成

①注册JedisConnectionFactory

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisPassword;
import org.springframework.data.redis.connection.RedisStandaloneConfiguration;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;

import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;

@Configuration
public class RedisConfig {

 @Value("${redis.pool.maxTotal}")
 private Integer maxTotal;

 @Value("${redis.pool.minIdle}")
 private Integer minIdle;

 @Value("${redis.pool.maxIdle}")
 private Integer maxIdle;

 @Value("${redis.pool.maxWaitMillis}")
 private Integer maxWaitMillis;

 @Value("${redis.url}")
 private String redisUrl;

 @Value("${redis.port}")
 private Integer redisPort;

 @Value("${redis.timeout}")
 private Integer redisTimeout;

 @Value("${redis.password}")
 private String redisPassword;

 @Value("${redis.db.payment}")
 private Integer paymentDataBase;

 private JedisPoolConfig jedisPoolConfig() {
  JedisPoolConfig config = new JedisPoolConfig();
  config.setMaxTotal(maxTotal);
  config.setMinIdle(minIdle);
  config.setMaxIdle(maxIdle);
  config.setMaxWaitMillis(maxWaitMillis);
  return config;
 }

 @Bean
 public JedisPool jedisPool() {
  JedisPoolConfig config = this.jedisPoolConfig();
  JedisPool jedisPool = new JedisPool(config, redisUrl, redisPort, redisTimeout, redisPassword);
  return jedisPool;
 }

 @Bean(name = "jedisConnectionFactory")
 public JedisConnectionFactory jedisConnectionFactory() {
  RedisStandaloneConfiguration redisStandaloneConfiguration = new RedisStandaloneConfiguration();
  redisStandaloneConfiguration.setDatabase(paymentDataBase);
  redisStandaloneConfiguration.setHostName(redisUrl);
  redisStandaloneConfiguration.setPassword(RedisPassword.of(redisPassword));
  redisStandaloneConfiguration.setPort(redisPort);

  return new JedisConnectionFactory(redisStandaloneConfiguration);
 }
}

②注册监听器

import org.springframework.data.redis.connection.Message;
import org.springframework.data.redis.connection.MessageListener;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service(value ="paymentListener")
public class PaymentListener implements MessageListener {

 @Override
 @Transactional
 public void onMessage(Message message, byte[] pattern) {
  // 过期事件处理流程
 }
}

③配置订阅对象

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.listener.PatternTopic;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
import org.springframework.data.redis.listener.adapter.MessageListenerAdapter;

@Configuration
@AutoConfigureAfter(value = RedisConfig.class)
public class PaymentListenerConfig {

 @Autowired
 @Qualifier(value = "paymentListener")
 private PaymentListener paymentListener;

 @Autowired
 @Qualifier(value = "paymentListener")
 private JedisConnectionFactory connectionFactory;

 @Value("${redis.db.payment}")
 private Integer paymentDataBase;

 @Bean
 RedisMessageListenerContainer redisMessageListenerContainer(MessageListenerAdapter listenerAdapter) {
        RedisMessageListenerContainer container = new RedisMessageListenerContainer();
        container.setConnectionFactory(connectionFactory);
        // 监听paymentDataBase 库的过期事件
        String subscribeChannel = "__keyevent@" + paymentDataBase + "__:expired";
        container.addMessageListener(listenerAdapter, new PatternTopic(subscribeChannel));
        return container;
 }

 @Bean
    MessageListenerAdapter listenerAdapter() {
        return new MessageListenerAdapter(paymentListener);
    }
}

paymentDataBase 库元素过期后就会跳入PaymentListener 的onMessage(Message message, byte[] pattern)方法。

到此这篇关于Redis实现订单自动过期功能的示例代码的文章就介绍到这了,更多相关Redis 订单自动过期内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Redis中键的过期删除策略深入讲解

    如果一个键过期了,那么它什么时候会被删除呢? 这个问题有三种可能的答案,它们分别代表了三种不同的删除策略: 定时删除:在设置键的过期时间的同时,创建一个定时器( timer ). 让定时器在键的过期时间来临时,立即执行对键的删除操作. 惰性删除:放任键过期不管,但是每次从键空间中获取键时,都检查取得的键是否过期,如果过期的话,就删除该键;如果没有过期,就返回该键. 定期删除: 每隔一段时间,程序就对数据库进行一次检查,删除里面的过期键.至于要删除多少过期键,以及要检查多少个数据库, 则由算法决定

  • Redis 对过期数据的处理方法

    在 redis 中,对于已经过期的数据,Redis 采用两种策略来处理这些数据,分别是惰性删除和定期删除 惰性删除 惰性删除不会去主动删除数据,而是在访问数据的时候,再检查当前键值是否过期,如果过期则执行删除并返回 null 给客户端,如果没有过期则返回正常信息给客户端. 它的优点是简单,不需要对过期的数据做额外的处理,只有在每次访问的时候才会检查键值是否过期,缺点是删除过期键不及时,造成了一定的空间浪费. 源码 robj *lookupKeyReadWithFlags(redisDb *db,

  • Python操作Redis之设置key的过期时间实例代码

    Expire 命令用于设置 key 的过期时间.key 过期后将不再可用. r.set('2', '4028b2883d3f5a8b013d57228d760a93') #成功就返回True 失败就返回False,下面的20表示是20秒 print r.expire('2',20) #如果时间没事失效我们能得到键为2的值,否者是None print r.get('2') 对于一个已经存在的key,我们可以设置其过期时间,到了那个时间后,当你再去访问时,key就不存在了 有两种方式可以设置过期时间

  • spring boot+redis 监听过期Key的操作方法

    前言: 在订单业务中,有时候需要对订单设置有效期,有效期到了后如果还未支付,就需要修改订单状态.对于这种业务的实现,有多种不同的办法,比如: 1.使用querytz,每次生成一个订单,就创建一个定时任务,到期后执行业务代码: 2.rabbitMq中的延迟队列: 3.对Redis的Key进行监控: 1.引入依赖 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring

  • Redis中键值过期操作示例详解

    1.过期设置 Redis 中设置过期时间主要通过以下四种方式: expire key seconds:设置 key 在 n 秒后过期: pexpire key milliseconds:设置 key 在 n 毫秒后过期: expireat key timestamp:设置 key 在某个时间戳(精确到秒)之后过期: pexpireat key millisecondsTimestamp:设置 key 在某个时间戳(精确到毫秒)之后过期: 下面分别来看以上这些命令的具体实现. 1)expire:N

  • Redis中的数据过期策略详解

    1.Redis中key的的过期时间 通过EXPIRE key seconds命令来设置数据的过期时间.返回1表明设置成功,返回0表明key不存在或者不能成功设置过期时间.在key上设置了过期时间后key将在指定的秒数后被自动删除.被指定了过期时间的key在Redis中被称为是不稳定的. 当key被DEL命令删除或者被SET.GETSET命令重置后与之关联的过期时间会被清除 127.0.0.1:6379> setex s 20 1 OK 127.0.0.1:6379> ttl s (intege

  • python redis 批量设置过期key过程解析

    这篇文章主要介绍了python redis 批量设置过期key过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 在使用 Redis.Codis 时,我们经常需要做一些批量操作,通过连接数据库批量对 key 进行操作: 关于未过期: 1.常有大批量的key未设置过期,导致内存一直暴增 2.rd需求 扫描出这些key,rd自己处理过期(一般dba不介入数据的修改) 3.dba 批量设置过期时间,(一般测试可以直接批量设置,线上谨慎操作) 通过

  • SpringBoot如何整合redis实现过期key监听事件

    可以用于简单的过期订单取消支付.7天自动收货场景中 1.Spring Boot整合redis 参考 https://www.jb51.net/article/170687.htm 2.打开redis服务的配置文件添加notify-keyspace-events Ex 如果是注释了,就取消注释 Linux安装redis:https://www.jb51.net/article/193265.htm Windows安装redis:https://www.jb51.net/article/176040

  • springboot+redis过期事件监听实现过程解析

    1 修改 redis.conf配置文件: K Keyspace events, published with keyspace@ prefix事件 E Keyevent events, published with keyevent@ prefix g Generic commands (non-type specific) like DEL, EXPIRE, RENAME, - $ String commands l List commands s Set commands h Hash co

  • Redis有效时间设置以及时间过期处理操作

    本文对redis的过期处理机制做个简单的概述,让大家有个基本的认识. Redis中有个设置时间过期的功能,即对存储在redis数据库中的值可以设置一个过期时间.作为一个缓存数据库,这是非常实用的.如我们一般项目中的token或者一些登录信息,尤其是短信验证码都是有时间限制的,按照传统的数据库处理方式,一般都是自己判断过期,这样无疑会严重影响项目性能. 一.有效时间设置: redis对存储值的过期处理实际上是针对该值的键(key)处理的,即时间的设置也是设置key的有效时间.Expires字典保存

随机推荐