Redis消息通知
push channel body如上是redis发送消息的基本格式, channel:通道信息, body:内容 比如:publish aaa xxx publish aaa ttt
向通道aaa发送了两条消息,一条是消息内容是xxx,另一条消息内容是ttt,以上的内容都是在redis-cli中执行的.那么对应的代码在springboot中怎么接收该消息呢
首先需要再redis配置中配置监听器,并设置监听的通道信息
package com.wqeq.test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.listener.PatternTopic;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
/**
* @description:Redis中间件配置类,使用spring-data-redis集成,自动从application.yml中加载redis配置
*
*/
@Configuration
public class RedisMsgListenConfig {
@Autowired
private RedisTestMsgListener redisTestMsgListener;
/**
* redis消息监听器容器 可以添加多个监听不同话题的redis监听器,只需要把消息监听器和相应的消息订阅处理器绑定,该消息监听器
* 通过反射技术调用消息订阅处理器的相关方法进行一些业务处理
*
* @param connectionFactory
* @return
*/
@Bean
RedisMessageListenerContainer container(RedisConnectionFactory connectionFactory) {
RedisMessageListenerContainer container = new RedisMessageListenerContainer();
container.setConnectionFactory(connectionFactory);
//配置redis消息监听通道
container.addMessageListener(redisTestMsgListener, new PatternTopic("aaa"));
container.addMessageListener(redisTestMsgListener, new PatternTopic("__keyevent@2__:del"));
container.addMessageListener(redisTestMsgListener, new PatternTopic("__keyspace@2__:aaa"));
return container;
}
}
这里我们监听了3个通道的消息,分别是
aaa
keyevent@2:del
keyspace@2:aaa
这里使用RedisTestMsgListener的实例来接收消息,可以注意到,这里3个通道使用的同一个消息监听来处理,因为仅作为测试不需要那么麻烦写多个,实际根据自己的业务来决定。
然后接收消息的代码如下
package com.wqeq.test;
import org.jetbrains.annotations.NotNull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.connection.Message;
import org.springframework.data.redis.connection.MessageListener;
import org.springframework.stereotype.Component;
/**
* 接收来自redis的消息通知
*/
@Component
public class RedisTestMsgListener implements MessageListener {
private final static Logger logger = LoggerFactory.getLogger(RedisTestMsgListener.class);
@Override
public void onMessage(@NotNull Message message, byte[] bytes) {
//简单输出通道和内容信息
logger.info("收到消息:"+new String(message.getChannel())+"-->"+new String(message.getBody()));
}
}
代码ok了,那来跑一遍测试吧
在redis-cli里执行发送简单消息"helloworld",^-^(每个程序员都会心一笑!)
publish aaa helloworld
查看代码监听的输出结果
从结果可以看到是符合预期的,aaa是我们可以理解的通道,但是另外两个通道比较奇怪keyevent@2:del
keyspace@2:aaa
这个是什么东西?为什么要写这么奇怪的通道?并且也是可以发送的,对应语句如下
publish __keyevent@2__:del aaa
publish __keyspace@2__:aaa del
同样可以收到结果,对应输出如下
结果也是符合预期的。这里为什么要用这样特别的写法,其实这种是系统的自身的发送消息格式,也就是告诉我们虽然可以但是最好不要由私人调用,在写具体业务的时候的发送的消息格式要尽量避开这种写法。
到目前为止可能还有人不知道如何在代码里面发送消息,其实非常简单,直接上代码
redisTemplate.convertAndSend("aaa","hello");
是不是特别简单?那么哪些情况会触发redis自身的消息发送呢,目前已知有redis的事件操作和key操作,比如马上能想到的key的删除,修改,过期等等
现在在来看看这两种写法的具体含义:
如果想知道某个事件的触发是由什么key引起的使用keyevent
publish keyevent@*:event aaa
上面可替换的部分有
*代表第几个库的key触发了事件,redis默认16个库,可以填任何一个数字,也可以直接使用星号代表任何库
event代表了事件,del,expire,rename...
aaa代表消息的发送通道,对应接收需要监控该通道
例子
publish __keyevent@2__:del aaa
所以上面语句表示的意思是redis的2号库触发了删除key事件,然后redis系统会自动发送一条删除事件的消息,消息内容是被删除的key为aaa,然后我们就可以在代码中监听事件的变化,业务上再做对应的处理,该消息事件是作为主体。
如果想知道某个key发生了哪些变化使用keyspace
publish keyspace@*:aaa del
同理上面可替换的部分有
*代表第几个库的key触发了事件
event代表了事件,del,expire,rename...
aaa代表消息的通道
publish __keyspace@2__:aaa del
所以上面语句表示的意思是redis的2号库一个key为aaa发生了改变,该key的改变触发了redis的消息通知,消息内容是该key的具体变化(也就是del),跟前面相比理解主体变化了
当然如上两个推送需要redis自身支持,已知目前redis要支持该功能至少版本要大于2.8.0
其次,这些推送是要占用服务器资源的,所以需要主动开启,开启方式是在redis.conf文件中加上(如果存在则开启)如下代码并重启redis服务器
发表回复
要发表评论,您必须先登录。