talk is cheap, show me the code.html
方式二:修改配置文件java
redis.conf
redis
# 默認 notify-keyspace-events "" notify-keyspace-events Ex
方式二:命令行開啓spring
CONFIG SET notify-keyspace-events Ex CONFIG GET notify-keyspace-events
notify-keyspace-events 選項的默認值爲空數據庫
notify-keyspace-events 的參數能夠是如下字符的任意組合, 它指定了服務器該發送哪些類型的通知。服務器
字符 | 發送的通知 |
---|---|
K | 鍵空間通知,全部通知以 keyspace@
|
E | 鍵事件通知,全部通知以 keyevent@
|
g | DEL 、 EXPIRE 、 RENAME 等類型無關的通用命令的通知 |
$ | 字符串命令的通知 |
l | 列表命令的通知 |
s | 集合命令的通知 |
h | 哈希命令的通知 |
z | 有序集合命令的通知 |
x | 過時事件:每當有過時鍵被刪除時發送 |
e | 驅逐(evict)事件:每當有鍵由於 maxmemory 政策而被刪除時發送 |
A | 參數 g$lshzxe 的別名 |
初始化一個Spring Boot
項目dom
pom.xml
ide
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency> </dependencies>
定義配置類RedisListenerConfig
spring-boot
@Configuration public class RedisListenerConfig { @Bean RedisMessageListenerContainer container(RedisConnectionFactory connectionFactory) { RedisMessageListenerContainer container = new RedisMessageListenerContainer(); container.setConnectionFactory(connectionFactory); return container; } }
定義數據生產類ProviderDataToRedis
測試
@Slf4j @Component public class ProviderDataToRedis implements CommandLineRunner { @Autowired private StringRedisTemplate stringRedisTemplate; @Override public void run(String... args) throws Exception { int[] num = new int[]{1}; Random random = new Random(); while (true) { int max = random.nextInt(5); IntStream.range(0, max).forEach(n -> stringRedisTemplate.opsForValue().set(String.format("mq:s1:%s", ++num[0]), "已預訂", 5, TimeUnit.SECONDS)); log.info("放了 {} 條數據到redis...", max); TimeUnit.SECONDS.sleep(3); } } }
定義監聽器 實現KeyExpirationEventMessageListener
接口
查看源碼發現,該接口監聽全部db的過時事件keyevent@*:expired"
定義Status1ExpirationListener
監聽狀態1到期
@Slf4j @Component public class Status1ExpirationListener extends KeyExpirationEventMessageListener { public Status1ExpirationListener(RedisMessageListenerContainer listenerContainer) { super(listenerContainer); } @Autowired private StringRedisTemplate stringRedisTemplate; @Override public void onMessage(Message message, byte[] pattern) { // 用戶作本身的業務處理便可,注意message.toString()能夠獲取失效的key String expiredKey = message.toString(); if (expiredKey.startsWith("mq:s1:")) { log.info("-----------------------------------"); log.info(String.format("過時key[%s]", expiredKey)); String newKey = String.format("mq:s2:%s", expiredKey.substring(6)); String newValue = "行程中"; stringRedisTemplate.opsForValue().set(newKey, newValue, 3, TimeUnit.SECONDS); log.info(String.format("%s: %s", newKey, newValue)); log.info("-----------------------------------"); } } }
定義Status2ExpirationListener
監聽狀態2到期
@Slf4j @Component public class Status2ExpirationListener extends KeyExpirationEventMessageListener { public Status2ExpirationListener(RedisMessageListenerContainer listenerContainer) { super(listenerContainer); } @Override public void onMessage(Message message, byte[] pattern) { // 用戶作本身的業務處理便可,注意message.toString()能夠獲取失效的key String expiredKey = message.toString(); if (expiredKey.startsWith("mq:s2:")) { log.info("***********************************"); log.info(String.format("過時key[%s]", expiredKey)); log.info("[{}]行程已完成,修改數據庫狀態。", newKey); log.info("***********************************"); } } }
... 2021-01-25 23:16:58.012 INFO 55511 --- [ main] n.y.tools.listener.ProviderDataToRedis : 放了 4 條數據到redis... 2021-01-25 23:17:00.037 INFO 55511 --- [ container-1070] c.i.r.l.Status1ExpirationListener : ----------------------------------- 2021-01-25 23:17:00.037 INFO 55511 --- [ container-1070] c.i.r.l.Status1ExpirationListener : 過時key[mq:s1:272] 2021-01-25 23:17:00.037 INFO 55511 --- [ container-1072] c.i.r.l.Status1ExpirationListener : ----------------------------------- 2021-01-25 23:17:00.037 INFO 55511 --- [ container-1072] c.i.r.l.Status1ExpirationListener : 過時key[mq:s1:271] 2021-01-25 23:17:00.039 INFO 55511 --- [ container-1070] c.i.r.l.Status1ExpirationListener : mq:s2:272: 行程中 2021-01-25 23:17:00.039 INFO 55511 --- [ container-1072] c.i.r.l.Status1ExpirationListener : mq:s2:271: 行程中 2021-01-25 23:17:00.039 INFO 55511 --- [ container-1070] c.i.r.l.Status1ExpirationListener : ----------------------------------- 2021-01-25 23:17:00.039 INFO 55511 --- [ container-1072] c.i.r.l.Status1ExpirationListener : ----------------------------------- 2021-01-25 23:17:00.140 INFO 55511 --- [ container-1075] c.i.r.l.Status2ExpirationListener : *********************************** 2021-01-25 23:17:00.140 INFO 55511 --- [ container-1075] c.i.r.l.Status2ExpirationListener : 過時key[mq:s2:270] 2021-01-25 23:17:00.140 INFO 55511 --- [ container-1075] c.i.r.l.Status2ExpirationListener : [270]行程已完成,修改數據庫狀態。 2021-01-25 23:17:00.140 INFO 55511 --- [ container-1075] c.i.r.l.Status2ExpirationListener : *********************************** 2021-01-25 23:17:00.242 INFO 55511 --- [ container-1077] c.i.r.l.Status2ExpirationListener : *********************************** 2021-01-25 23:17:00.242 INFO 55511 --- [ container-1077] c.i.r.l.Status2ExpirationListener : 過時key[mq:s2:269] 2021-01-25 23:17:00.242 INFO 55511 --- [ container-1079] c.i.r.l.Status2ExpirationListener : *********************************** 2021-01-25 23:17:00.242 INFO 55511 --- [ container-1079] c.i.r.l.Status2ExpirationListener : 過時key[mq:s2:268] 2021-01-25 23:17:00.242 INFO 55511 --- [ container-1077] c.i.r.l.Status2ExpirationListener : [269]行程已完成,修改數據庫狀態。 2021-01-25 23:17:00.242 INFO 55511 --- [ container-1077] c.i.r.l.Status2ExpirationListener : *********************************** 2021-01-25 23:17:00.242 INFO 55511 --- [ container-1079] c.i.r.l.Status2ExpirationListener : [268]行程已完成,修改數據庫狀態。 2021-01-25 23:17:00.242 INFO 55511 --- [ container-1079] c.i.r.l.Status2ExpirationListener : *********************************** 2021-01-25 23:17:00.546 INFO 55511 --- [ container-1081] c.i.r.l.Status2ExpirationListener : *********************************** 2021-01-25 23:17:00.546 INFO 55511 --- [ container-1081] c.i.r.l.Status2ExpirationListener : 過時key[mq:s2:267] 2021-01-25 23:17:00.546 INFO 55511 --- [ container-1081] c.i.r.l.Status2ExpirationListener : [267]行程已完成,修改數據庫狀態。 2021-01-25 23:17:00.546 INFO 55511 --- [ container-1081] c.i.r.l.Status2ExpirationListener : *********************************** ...
從測試輸出的日誌中能夠看出,線程一直在增長,這個問題還有待解決!