如何用spring订阅redis键空间事件

问题描述 投票:0回答:1

我的环境

  • Mac 文图拉 13.6.3
  • 铁木林17
  • SpringBoot 3.2.1
  • org.springframework.boot:spring-boot-starter-data-redis
  • 在本地机器上运行的redis集群。 (本地主机:7001,本地主机:7002,本地主机:7003

我想做的事

我想用spring从redis集群接收expire事件。

我做了什么

我连接到集群,并且密钥过期了

CONFIG SET notify-keyspace-events Ex

SET hi 123
EXPIRE hi 3

我的(java)代码

配置

package kr.co.yogiyo.payo.infrastructure.temporal;

import io.lettuce.core.ReadFrom;
import kr.co.yogiyo.payo.infrastructure.temporal.service.RedisExpireEventService;
import lombok.RequiredArgsConstructor;
import org.springframework.boot.autoconfigure.data.redis.RedisConnectionDetails;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisClusterConfiguration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.RedisNode;
import org.springframework.data.redis.connection.lettuce.LettuceClientConfiguration;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.listener.PatternTopic;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;

@RequiredArgsConstructor
@Configuration
public class RedisConfig {

  private final RedisConnectionDetails redisConnectionDetails;

  @Bean
  public RedisConnectionFactory redisConnectionFactory() {
    RedisConnectionDetails.Cluster cluster = redisConnectionDetails.getCluster();
    RedisClusterConfiguration clusterConfiguration = new RedisClusterConfiguration();
    for (RedisConnectionDetails.Node node : cluster.getNodes()) {
      clusterConfiguration.addClusterNode(new RedisNode(node.host(), node.port()));
    }

    LettuceClientConfiguration clientConfig =
        LettuceClientConfiguration.builder().readFrom(ReadFrom.REPLICA_PREFERRED).build();

    return new LettuceConnectionFactory(clusterConfiguration, clientConfig);
  }

  @Bean
  RedisMessageListenerContainer keyExpirationListenerContainer(
      RedisConnectionFactory connectionFactory, RedisExpireEventService redisExpireEventService) {
    RedisMessageListenerContainer listenerContainer = new RedisMessageListenerContainer();
    listenerContainer.setConnectionFactory(connectionFactory);
    listenerContainer.addMessageListener(
        redisExpireEventService, new PatternTopic("__keyevent@*__:expired"));
    return listenerContainer;
  }
}

服务

package kr.co.yogiyo.payo.infrastructure.temporal.service;

import lombok.RequiredArgsConstructor;
import org.springframework.data.redis.connection.Message;
import org.springframework.data.redis.connection.MessageListener;
import org.springframework.stereotype.Service;

@Service
@RequiredArgsConstructor
public class RedisExpireEventService implements MessageListener {
  @Override
  public void onMessage(Message message, byte[] pattern) {
    System.out.println("Message received: " + message.toString());
  }
}

应用程序.yml

spring:
  main:
    banner-mode: off
    allow-bean-definition-overriding: true
  jackson:
    property-naming-strategy: SNAKE_CASE
  data:
    redis:
      host: ${PAYO_REDIS_MASTER_HOST:localhost}
      port: ${PAYO_REDIS_MASTER_PORT:7002}
      cluster:
        nodes: ${PAYO_REDIS_REPLICATION_NODES:localhost:7001,localhost:7002,localhost:7003}

spring运行良好,但是当key过期时没有任何反应。 (我设置断点并以调试模式运行,仍然没有任何反应)

工作Python代码

我尝试使用Python,它的工作就像魅力......我想用spring订阅该活动。

import redis


def main():
    # Connect to Redis
    r = redis.Redis(host='localhost', port=7002, db=0)

    # Subscribe to the '__keyevent@0__:expired' channel
    pubsub = r.pubsub()
    pubsub.psubscribe('__keyevent@*__:expired')

    # Start listening for messages
    for message in pubsub.listen():
        print("something expired! ", message)

if __name__ == "__main__":
    main()

something expired!  {'type': 'psubscribe', 'pattern': None, 'channel': b'__keyevent@*__:expired', 'data': 1}
something expired!  {'type': 'pmessage', 'pattern': b'__keyevent@*__:expired', 'channel': b'__keyevent@0__:expired', 'data': b'hi'}

你们能让我知道我的java代码中缺少什么吗?

java spring redis spring-data-redis
1个回答
0
投票

试试这个

@Configuration
public class RedisConfig {

    @Bean
    public RedisMessageListenerContainer keyExpirationListenerContainer(
            RedisConnectionFactory connectionFactory,
            RedisExpireEventService redisExpireEventService) {
        RedisMessageListenerContainer listenerContainer = new RedisMessageListenerContainer();
        listenerContainer.setConnectionFactory(connectionFactory);
        listenerContainer.addMessageListener(
                redisExpireEventService,
                new PatternTopic("__keyevent@*__:expired"));
        return listenerContainer;
    }
}

@Service
public class RedisExpireEventService implements MessageListener {

    @Override
    public void onMessage(Message message, byte[] pattern) {
        // Handle the key expiration event
        String expiredKey = new String(message.getBody());
        System.out.println("Key expired: " + expiredKey);
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.