过期的按键触发事件-Spring数据Redis

tin*_*ard 5 spring redis spring-data spring-data-redis

我正在尝试使用spring数据redis设置Key过期事件处理程序,但无法使其正常工作。我做了一些研究,但没有达到预期的结果。不知道我在想什么。我想在redis缓存上的密钥过期时记录一条消息。

@Configuration
@EnableRedisRepositories
public class RedisConfig {

    @Bean 
    StringRedisTemplate stringRedisTemplate(){
        StringRedisTemplate stringRedisTemplate = new StringRedisTemplate(jedisConnectionFactory());
        return stringRedisTemplate;
    }

    @Bean
    RedisMessageListenerContainer redisContainer() {
        RedisMessageListenerContainer container 
          = new RedisMessageListenerContainer(); 
        container.setConnectionFactory(jedisConnectionFactory()); 
        container.addMessageListener(messageListener(), topic()); 
        return container; 
    }

    @Bean
    MessageListenerAdapter messageListener() { 
        return new MessageListenerAdapter(new RedisMessageSubscriber());
    }

    @Bean
    MessagePublisher redisPublisher() { 
        return new RedisMessagePublisher();
    }

    @Bean
    ChannelTopic topic() {
        return new ChannelTopic("messageQueue");
    }
}


public interface MessagePublisher {
    void publish(String message);
}

public class RedisMessagePublisher implements MessagePublisher {

    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    @Autowired
    private ChannelTopic topic;

    public void publish(String message) {
        stringRedisTemplate.convertAndSend(topic.getTopic(), message);
    }
}

@Service
public class RedisMessageSubscriber implements MessageListener {

    private static final Logger LOG = Logger.getLogger(RedisMessageSubscriber.class);

    public static List<String> messageList = new ArrayList<String>();

    @Override
    public void onMessage(Message message, byte[] pattern) {
        messageList.add(message.toString());
    }

}
Run Code Online (Sandbox Code Playgroud)

有人可以帮忙吗?谢谢

Mon*_*mul 5

首先,需要为redis中的expire事件启用keyspace通知。默认情况下,键空间事件通知是禁用的,因为该功能虽然不太明智,但会占用一些CPU资源。使用redis.conf的notify-keyspace-events或通过CONFIG SET启用通知。

notify-keyspace-events "Ex"
Run Code Online (Sandbox Code Playgroud)

完成redis后,您需要使用模式主题配置消息监听器"__keyevent@*__:expired"。这里是代码示例。

侦听器类:

@Component
public class ExpirationListener implements MessageListener {
    private static final Logger logger = LoggerFactory.getLogger(ExpirationListener.class);

    @Override
    public void onMessage(Message message, byte[] bytes) {
        String key = new String(message.getBody());
        logger.debug("expired key: {}", key);
    }
}
Run Code Online (Sandbox Code Playgroud)

组态:

@Bean
RedisMessageListenerContainer keyExpirationListenerContainer(RedisConnectionFactory connectionFactory, ExpirationListener expirationListener) {
    RedisMessageListenerContainer listenerContainer = new RedisMessageListenerContainer();
    listenerContainer.setConnectionFactory(connectionFactory);
    listenerContainer.addMessageListener(expirationListener, new PatternTopic("__keyevent@*__:expired"));
    listenerContainer.setErrorHandler(e -> logger.error("There was an error in redis key expiration listener container", e));
    return listenerContainer;
}
Run Code Online (Sandbox Code Playgroud)

  • `@EnableRedisRepositories(enableKeyspaceEvents = RedisKeyValueAdapter.EnableKeyspaceEvents.ON_STARTUP)` 启用键空间事件,而无需干扰 Redis 控制台或配置文件。 (2认同)