redis消息模式
来源:互联网 发布:商务中国域名转出 编辑:程序博客网 时间:2024/06/03 20:18
消息通知
一般来说,消息队列有两种场景,一种是生产者消费者模式,一种是发布者订阅者模式。利用redis这两种场景的消息队列都能实现。
1、生产者消费者模式
生产者生产消息放到队列中,多个消费者同时监听队列,谁先抢到消息谁就会从队列中取走消息,即对于每个消息最多只能被一个消费者拥有。
具体的方法就是创建一个任务队列,生产者主动lpush消息,而消费者去rpop数据。但是这样存在一个问题,就是消费者需要主动去请求数据,周期性的请求会造成资源的浪费。如果可以实现一旦有新消息加入队列就通知消费者就好了,这时借助brpop命令就可以实现这样的需求。brpop和rpop命令相似,唯一区别就是当列表中没有元素时,brpop命令会一直阻塞住连接,直到有新元素加入。
BRPOP key timeout
brpop命令接收两个参数,第一个参数key为键值,第二个参数timeout为超时时间。BRPOP命令取数据时候,如果暂时不存在数据,该命令会一直阻塞直到达到超时时间。如果timeout设置为0,那么就会无限等待下去。
2、发布者订阅者模式
发布者生产消息放到队列里,多个监听队列的订阅者都会受到同一份消息。
生产者使用下面命令来发布消息:
PUBLISH CHANNEL MESSAGE
订阅者通过下面的命令来订阅消息,执行subscribe命令后,客户端进入订阅状态,处于此状态的客户端不能使用4个属于“发布/订阅”模型的命令之外的命令。另外,可以使用subscribe channel1.1 channel1.2 ... 同时订阅多个频道。
SUBSCRIBE CHANNEL
3、Java实现的redis的消息队列
在jedis中,有对应的方法进行订阅和发布,为了传输对象,需要将对象进行序列化,并封装成字符串进行处理。
下面我们要实现三个类,一个对应publish,一个对应subscribe,一个对应要传递的对象实体类:
实体类:
import java.io.Serializable;/** * 实体类 * 封装消息 * @author Administrator * */public class Message implements Serializable{ private static final long serialVersionUID = 1L; private String title; private String content; public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } public String getContent() { return content; } public void setContent(String content) { this.content = content; }}
Publish类:
import java.io.ByteArrayOutputStream;import java.io.ObjectOutputStream;import redis.clients.jedis.Jedis;/** * 发布者,用于发布消息 * @author Administrator * */public class TestPub{ public static void main(String[] args) { Jedis jedis = new Jedis("127.0.0.1"); try { Message message = new Message(); message.setTitle("体育新闻"); message.setContent("著名NBA球星科比退役了!"); ByteArrayOutputStream baos = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(baos); oos.writeObject(message); String msg1 = baos.toString("ISO-8859-1"); jedis.publish("foo", msg1); } catch (Exception e) { e.printStackTrace(); } jedis.close(); }}
Subscribe类:
import java.io.ByteArrayInputStream;import java.io.ObjectInputStream;import redis.clients.jedis.Jedis;import redis.clients.jedis.JedisPubSub;/** * 订阅者,用于接收消息 * @author Administrator * */public class TestSub{ public static void main(String[] args) { Jedis jedis = new Jedis("127.0.0.1"); JedisPubSub jedisPubSub = new JedisPubSub() { @Overridepublic void onUnsubscribe(String channel, int subscribedChannels) { // 取消订阅时候的处理 System.out.println("1");}@Overridepublic void onSubscribe(String channel, int subscribedChannels) {// 初始化订阅时候的处理 System.out.println("2");}@Overridepublic void onPUnsubscribe(String pattern, int subscribedChannels) { // // 取消按表达式的方式订阅时候的处理 System.out.println("3");}@Overridepublic void onPSubscribe(String pattern, int subscribedChannels) { // // 初始化按表达式的方式订阅时候的处理 System.out.println("4");}@Overridepublic void onPMessage(String pattern, String channel,String message) {//// 取得按表达式的方式订阅的消息后的处理 System.out.println("5");} @Override public void onMessage(String channel, String message) {// 取得订阅的消息后的处理 try { ByteArrayInputStream bis = new ByteArrayInputStream(message.getBytes("ISO-8859-1"));
// 此处指定字符集将字符串编码成字节数组,此处的字符集需要与发布时的字符集保持一致 ObjectInputStream ois = new ObjectInputStream(bis); Message message2= (Message) ois.readObject(); System.out.println(message2.getTitle()+"\n"+message2.getContent()); } catch (Exception e) { e.printStackTrace(); } finally { } } }; jedis.subscribe(jedisPubSub, "foo"); jedis.close(); }}
- redis消息模式
- redis 消息队列 发布、订阅模式
- Spring Boot 与Redis 集成实现消息发布/订阅模式
- redis 消息队列发布订阅模式spring boot实现
- 消息模式
- 消息模式
- Redis消息通知
- Redis消息队列
- Redis-消息订阅
- redis 消息队列
- Redis消息订阅
- Redis 消息队列运用
- 消息队列------Redis
- Redis实现消息队列
- redis消息订阅功能分析
- redis实现消息队列
- redis实现消息队列
- redis实现消息队列
- 记一次 ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/tmp/mysql.sock’(2) 排错流程
- iOS 之单例 代理 通知
- Android 5.0、6.0的那(xin)些(kong)事(jian)
- openwrt单独编译package包
- APT Hash sum mismatch错误的常见解决方法总结
- redis消息模式
- Android ListView性能提升小技巧
- list 排序问题
- Android ListView优化思路12则
- 根据字符串中出现的字符逐个打印各字符出现次数
- UTF—8与UTF—8(无bom)格式相比有什么不同
- 洛谷 P1781 宇宙总统
- selenium使用Xpath定位的四种方法
- PHP请求远程地址设置超时时间