redis 消息发布订阅与消息队列
来源:互联网 发布:高斯滤波算法matlab 编辑:程序博客网 时间:2024/05/16 02:03
redis可以实现消息的发布订阅,可以用作java中的订阅发布模式
纯粹redis的发布订阅
redis客户端1中使用命令 SUBSCRIBE talk
可以订阅通道 talk上的消息
redis客户端2中也同样运行这个命令一起订阅通道 talk
redis客户端3使用命令 PUBLISH talk 'test'
可以发现客户端1和2同时受到消息
java实现
可以通过spring-redis中的redisTemplate工具辅助实现
1.发布消息
/** * redis发布消息 * * @param channel * @param message */public void sendMessage(String channel, String message) { redisTemplate.convertAndSend(channel, message);}
直接使用convertAndSend方法即可向指定的通道发布消息
2.监听消息
监听消息需要两步,消息监听类并在xml中注册这个类
监听类有两种实现方式一种是实现org.springframework.data.redis.connection.MessageListener接口,实现onMessage方法示例代码如下:
@Componentpublic class RedisMessageListener implements MessageListener { @Autowired private RedisTemplate<String, String> redisTemplate; private static Logger logger = Logger.getLogger(RedisMessageListener.class); @Override public void onMessage(Message message, byte[] pattern) { byte[] body = message.getBody();// 请使用valueSerializer byte[] channel = message.getChannel(); // 请参考配置文件,本例中key,value的序列化方式均为string。 // 其中key必须为stringSerializer。和redisTemplate.convertAndSend对应 String msgContent = (String) redisTemplate.getValueSerializer().deserialize(body); String topic = (String) redisTemplate.getStringSerializer().deserialize(channel); logger.info("redis--topic:" + topic + " body:" + msgContent); }}
也可以使用自己定义的类,方法名称自己定义,示例如下:
@Componentpublic class EventListener { private static Logger logger = Logger.getLogger(EventListener.class); public void getMessage(String message, String channel) { logger.info(message); }}
这两中方式实现的不同在于注册监听器时的配置略有不同
redis配置文件:
<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:redis="http://www.springframework.org/schema/redis" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.1.xsd http://www.springframework.org/schema/redis http://www.springframework.org/schema/redis/spring-redis-1.0.xsd"><bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig"> <property name="maxIdle" value="${redis.maxIdle}" /> <!-- <property name="maxActive" value="${redis.maxActive}" /> --> <property name="maxWaitMillis" value="${redis.maxWaitMillis}" /> <property name="testOnBorrow" value="${redis.testOnBorrow}" /></bean><!--注意使用订阅发布时,此bean必须命名为redisCOnnectionFactory,否则需要在listener中指明连接工厂--><bean id="redisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory" p:host-name="${redis.host}" p:port="${redis.port}" p:password="${redis.pass}" p:pool-config-ref="poolConfig"/><bean id="redisTemplate" class="org.springframework.data.redis.core.StringRedisTemplate"> <property name="connectionFactory" ref="redisConnectionFactory"/></bean><bean id="stringRedisSerializer" class="org.springframework.data.redis.serializer.StringRedisSerializer"/><!--此处注册监听器,需要指定通道名称(topic)(可以使用正则表达式*_等等),第一种为实现MessageListener接口的监听器的注册,第二种为自己定义的类的注册需要制定处理方法名称(不制定的默认方法为handleMessage,如果你的方法是这个名称可以不指定)与序列化的方式,推荐使用第一种方式--><redis:listener-container> <redis:listener ref="redisMessageListener" topic="talk"/> <redis:listener ref="eventListener" topic="talk*" method="getMessage" serializer="stringRedisSerializer"></redis:listener></redis:listener-container></beans>
redis消息队列
redis消息队列使用 redis中的list数据结构实现(左进右出)
/** * 向指定的列表左边插入数据 * * @param key * @param value * @return */public void leftPush(String key, String value) { redisTemplate.opsForList().leftPush(key, value);}
这个代码即可向指定的list中的左边插入值
/** * 弹出指定列表右边的数据(如果没有数据,在指定的时间内等待) * * @param key * @param timeout * @param unit * @return */public String rightPop(String key, long timeout, TimeUnit unit) { return redisTemplate.opsForList().rightPop(key, timeout, unit);}
以上代码可以从指定列表的右边弹出一个数据(如果没有,会等待指定时间返回空),只需要在工程中启动一个线程不停的使用这个方法即可实现消息队列的监听
@PostConstructpublic void messageListener() { new Thread(new Runnable() { @Override public void run() { while (true) { rightPop(....) .... } } }, "消息监听任务线程").start();}
对于弹出方法,可以使用
/** * 弹出指定列表右边,并向指定列表的左边插入(弹出列表如果没有元素,等待指定的时间) * * @param sourceKey * @param destinationKey * @param timeout * @param unit * @return */public String rightPopAndLeftPush(String sourceKey, String destinationKey, long timeout, TimeUnit unit) { return redisTemplate.opsForList().rightPopAndLeftPush(sourceKey, destinationKey, timeout, unit); }
这个方法优化代码,实现弹出的同时插入一个处理队列(事务)
阅读全文
0 0
- redis 消息发布订阅与消息队列
- redis消息队列订阅发布
- redis-消息发布与订阅
- redis-消息订阅与发布
- redis 消息队列 发布、订阅模式
- Redis消息订阅发布
- redis发布订阅消息
- redis消息订阅发布
- 消息队列模式:点对点 与 发布订阅
- 使用Redis构建消息队列和发布订阅系统
- redis的消息队列和发布订阅demo
- redis 消息队列发布订阅模式spring boot实现
- redis 消息订阅和发布
- redis发布及订阅消息
- Redis消息的发布/订阅
- 【Redis系列】Redis频道发布与消息订阅
- 消息队列中点对点与发布订阅区别
- 消息队列中点对点与发布订阅区别
- 瓦片地图setGlobalTileID无效
- struct stat结构体简介
- linux 学习系列-Linux 介绍
- Rust初识
- 多线程编程之线程间的通信——管道通信
- redis 消息发布订阅与消息队列
- 消除RGB受光照影响
- Android应用在未启动的情况下无法收到指定广播的问题总结
- HEVC学习(三) —— 帧内预测系列之一
- 可能是 Android 平台上最快的图片压缩框架
- BZOJ1079 着色方案(高维DP+神奇的状态)
- 教你如何从一个普通程序员,两年做到月薪 20 K+
- 重建smon_scn_time表和索引
- App.Config详解及读写操作