Redis键空间通知,实现延迟消息队列,归还订单库存

1、开启Redis的 notify-keyspace-events 功能

redis.conf配置文件中,添加notify-keyspace-events Ex;
E是键空间通知, x代表过期事件。需要重启redis

用redis-cli测试
1.订阅0号数据库的过期事件

127.0.0.1:6379> psubscribe __keyevent@0__:expired
Reading messages... (press Ctrl-C to quit)
1) "psubscribe"
2) "__keyevent@0__:expired"
3) (integer) 1

2设置name的过期时间

127.0.0.1:6379> setex name 10 77777

3.name过期后查看第一步的控制台,会收到如下消息

1) "pmessage"
2) "__keyevent@0__:expired"
3) "__keyevent@0__:expired"
4) "name"
2、在spring-boot中使用

推荐使用spring-boot-starter-data-redis
1.在applicatio.yml,配置reidis相关属性属性,listen-pattern: keyevent@7:expired是用来订阅0号数据库,所有键过期时事件

spring:
	redis:
	    database: 0  # Redis数据库索引(默认为0)
	    host: localhost # Redis服务器地址
	    port: 6379 # Redis服务器连接端口
	    password: 123456 # Redis服务器连接密码(默认为空)
	    listen-pattern: __keyevent@7__:expired

2.redis消息监听器容器

@Configuration
public class MessageListenerConfiguration {
    public String pattern = __keyevent@7__:expired;
    @Autowired
    private TopicMessageListener topicMessageListener;
    /**
     * redis消息监听器容器
     * 监听redis键空间通知配 监听key过期事件 __keyevent@7__:expired
     * @param redisConnectionFactory spring-boot redis链接信息
     */
    @Bean
    public RedisMessageListenerContainer listenerContainer(RedisConnectionFactory redisConnectionFactory) {
        RedisMessageListenerContainer container = new RedisMessageListenerContainer();
        container.setConnectionFactory(redisConnectionFactory);
        //订阅了一个叫 __keyevent@7__:expired 的通道
        Topic topic = new PatternTopic(this.pattern);
        container.addMessageListener(this.topicMessageListener, topic);
        return container;
    }
}

3.接收redis消息的类

/** 接收redis消息的类 */
@Component
public class TopicMessageListener implements MessageListener {

    /** 监听redis 键空间通知, key过期会执行这个方法 */
    @Override
    public void onMessage(Message message, byte[] bytes) {
        // redis回传的键名信息
        byte[] body = message.getBody();
        byte[] channel = message.getChannel();

        String expiredKey = new String(body);
        String topic = new String(channel);
        System.out.println(expiredKey);
        System.out.println(topic);
    }
}

4.把用户id+订单id作为key存到redis 如: 1,12作为key

@Service
public class OrderService {

    @Value("${snack.order.pay-time-limit}")
    private Integer payTimeLimit = 60;
    @Autowired
    private StringRedisTemplate stringRedisTemplate;
	/** 写入redis */
    private void sendToRedis(Long oid, Long uid) {
        String key = uid.toString() + "," + oid.toString();
        try {
            stringRedisTemplate.opsForValue().set(key, "1", this.payTimeLimit, TimeUnit.SECONDS);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

当支付时间过期时,会触发上面的onMessage方法,进行库存归还(业务逻辑自行编写)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值