Redis 캐시 만료는 Redis 구독 및 게시 기능 (pub / sub)을 통해 배포되므로 redis 이벤트 모니터링 및 게시를 활성화해야합니다.
redis 구성 파일을
수정 합니다. notify-keyspace-events ""를 notify-keyspace-events "Ex"로 수정하여
다시 시작합니다. Redis는
두 개의 클라이언트를 열어 구성이 적용되는지 테스트합니다.
클라이언트 1은 만료 시간을 모니터링합니다.
SUBSCRIBE __keyevent@0__:expired
클라이언트 2는 만료 시간이 1 초인 키를 설정합니다.
set ex_key ex_value ex 1
클라이언트 1이 만료 된 이벤트를 성공적으로 모니터링했습니다.
자바 모니터
pom 파일
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.sunyuqi</groupId>
<artifactId>redis_demo</artifactId>
<version>1.0-SNAPSHOT</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.3.RELEASE</version>
<relativePath/>
</parent>
<properties>
<java.version>9</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>
구성 클래스
package com.sunyuqi.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.RedisStandaloneConfiguration;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.JdkSerializationRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
@Configuration
@Profile("pubsub")
class RedisTemplateConfig {
@Bean
public LettuceConnectionFactory redisConnectionFactory() {
return new LettuceConnectionFactory(new RedisStandaloneConfiguration("127.0.0.1", 6379));
}
@Bean
public RedisTemplate redisTemplate(RedisConnectionFactory redisConnectionFactory) {
RedisTemplate redisTemplate = new RedisTemplate();
redisTemplate.setConnectionFactory(redisConnectionFactory);
// 可以配置对象的转换规则,比如使用json格式对object进行存储。
// Object --> 序列化 --> 二进制流 --> redis-server存储
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setValueSerializer(new JdkSerializationRedisSerializer());
return redisTemplate;
}
}
만료 된 메시지 리스너 클래스 캐시
package com.sunyuqi.pubsub;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import org.springframework.data.redis.connection.Message;
import org.springframework.data.redis.connection.MessageListener;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.listener.ChannelTopic;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
import org.springframework.stereotype.Component;
import java.util.Arrays;
@Component
@Profile("pubsub")
@Configuration
public class ExListener {
// 定义监听器
@Bean
public RedisMessageListenerContainer smsMessageListener(RedisConnectionFactory redisConnectionFactory) {
RedisMessageListenerContainer container = new RedisMessageListenerContainer();
container.setConnectionFactory(redisConnectionFactory);
SmsSendListener smsSendListener = new SmsSendListener();
container.addMessageListener(smsSendListener, Arrays.asList(new ChannelTopic("__keyevent@0__:expired")));
return container;
}
class SmsSendListener implements MessageListener {
@Override
public void onMessage(Message message, byte[] pattern) {
System.out.println("key: " + message + "已过期。");
}
}
}
테스트 클래스
package com.sunyuqi.pubsub;
import com.sunyuqi.SpringbootApplicationDemo;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.junit4.SpringRunner;
import java.util.concurrent.TimeUnit;
@RunWith(SpringRunner.class)
@SpringBootTest(classes = SpringbootApplicationDemo.class)
@ActiveProfiles("pubsub")
public class PubsubTest {
@Autowired
RedisTemplate redisTemplate;
@Test
public void test() throws InterruptedException {
//设置一秒钟过期
redisTemplate.opsForValue().set("ex_test","test",1,TimeUnit.SECONDS);
Thread.sleep(2000);
}
}
캐시 만료를 성공적으로 모니터링했습니다.