RabbitMQ入门教程(五):扇形交换机发布/订阅(Publish/Subscribe)
原文:RabbitMQ入门教程(五):扇形交换机发布/订阅(Publish/Subscribe)
版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。
分享一个朋友的人工智能教程。比较通俗易懂,风趣幽默,感兴趣的朋友可以去看看。
简介
本节主要演示交换机的广播类型fanout,广播类型不需要routingKey,交换机会将所有的消息都发送到每个绑定的队列中去。
在发布消息时可以只先指定交换机的名称,交换机的声明的代码可以放到消费者端进行声明,队列的声明也放在消费者端来声明。
发布订阅类似观察者模式设计模式,一般适用于当接收到某条消息时同时做多种类似的任务的处理,如一个发短信,另一个一个发邮件;一个插入数据库,另一个保存在文件等类似操作,扇形交换机将消息传送给不同的队列,不同的队列对同一种消息采取不同的行为。
扇形交换机是最基本的交换机类型,它所能做的事情非常简单———广播消息。扇形交换机会把能接收到的消息全部发送给绑定在自己身上的队列。因为广播不需要“思考”,所以扇形交换机处理消息的速度也是所有的交换机类型里面最快的。
生产者
public class Producer {
@Test
public void testBasicPublish() throws IOException, TimeoutException {
ConnectionFactory factory = new ConnectionFactory();
factory.setHost("127.0.0.1");
factory.setPort(AMQP.PROTOCOL.PORT);
factory.setUsername("mengday");
factory.setPassword("mengday");
Connection connection = factory.newConnection();
Channel channel = connection.createChannel();
String EXCHANGE_NAME = "exchange.fanout";
// 生产者不需要队列声明,也不需要声明交换机,只需要指定交换机的名称即可,队列和交换机的声明可以在消费者中声明
// 循环发布多条消息, 注意广播模式不需要routingKey, 可以写成"", 也可以随意写个名字,在消费者也随便写一个,生产者和消费者的routingKey的不一样看看可以不
for (int i = 0; i < 10; i++){
String message = "Hello RabbitMQ " + i;
// 广播类型不需要routingKey,但是不能写成null,可以写成空字符串""
channel.basicPublish(EXCHANGE_NAME, "", null, message.getBytes("UTF-8"));
}
// 关闭资源
channel.close();
connection.close();
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
消费者1
public class Consumer1 {
@Test
public void testBasicConsumer1() throws Exception{
ConnectionFactory factory = new ConnectionFactory();
factory.setHost("127.0.0.1");
factory.setPort(AMQP.PROTOCOL.PORT);
factory.setUsername("mengday");
factory.setPassword("mengday");
Connection connection = factory.newConnection();
final Channel channel = connection.createChannel();
channel.basicQos(1);
String QUEUE_NAME = "queue.fanout.q1";
String EXCHANGE_NAME = "exchange.fanout";
channel.queueDeclare(QUEUE_NAME, false, false, false, null);
// 声明交换机:指定交换机的名称和类型(广播:fanout)
channel.exchangeDeclare(EXCHANGE_NAME, BuiltinExchangeType.FANOUT);
// 在消费者端队列绑定
channel.queueBind(QUEUE_NAME, EXCHANGE_NAME, "");
System.out.println("Consumer Wating Receive Message");
Consumer consumer = new DefaultConsumer(channel){
@Override
public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
String message = new String(body, "UTF-8");
System.out.println(" [C] Received '" + message + "', 处理业务中...");
}
};
channel.basicConsume(QUEUE_NAME, true, consumer);
Thread.sleep(1000000);
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
消费者2
消费者2和消费者1仅仅是队列名称不一样而已
public class Consumer2 {
@Test
public void testBasicConsumer2() throws Exception{
ConnectionFactory factory = new ConnectionFactory();
factory.setHost("127.0.0.1");
factory.setPort(AMQP.PROTOCOL.PORT);
factory.setUsername("mengday");
factory.setPassword("mengday");
Connection connection = factory.newConnection();
final Channel channel = connection.createChannel();
channel.basicQos(1);
String QUEUE_NAME = "queue.fanout.q2";
String EXCHANGE_NAME = "exchange.fanout";
channel.queueDeclare(QUEUE_NAME, false, false, false, null);
// 在消费者端队列绑定
// 声明交换机:指定交换机的名称和类型(广播:fanout)
channel.exchangeDeclare(EXCHANGE_NAME, BuiltinExchangeType.FANOUT);
channel.queueBind(QUEUE_NAME, EXCHANGE_NAME, "");
System.out.println("Consumer Wating Receive Message");
Consumer consumer = new DefaultConsumer(channel){
@Override
public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
String message = new String(body, "UTF-8");
System.out.println(" [C] Received '" + message + "', 处理业务中...");
}
};
channel.basicConsume(QUEUE_NAME, true, consumer);
Thread.sleep(1000000);
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
运行效果
注意:先启动消费者,再启动生产者。可以看到两个消费者都收到同样的消息
分享一个朋友的人工智能教程。比较通俗易懂,风趣幽默,感兴趣的朋友可以去看看。
我的微信公众号:
RabbitMQ入门教程(五):扇形交换机发布/订阅(Publish/Subscribe)的更多相关文章
- RabbitMQ入门(3)——发布/订阅(Publish/Subscribe)
在上一篇RabbitMQ入门(2)--工作队列中,有一个默认的前提:每个任务都只发送到一个工作人员.这一篇将介绍发送一个消息到多个消费者.这种模式称为发布/订阅(Publish/Subscribe). ...
- RabbitMQ学习总结 第四篇:发布/订阅 Publish/Subscribe
目录 RabbitMQ学习总结 第一篇:理论篇 RabbitMQ学习总结 第二篇:快速入门HelloWorld RabbitMQ学习总结 第三篇:工作队列Work Queue RabbitMQ学习总结 ...
- ActiveMQ 快速入门教程系列 第二章 发布-订阅者模式实现
第二章我们会介绍怎样实现一个发布者对多个订阅者的消息传递 Topic和queue的最大区别在于topic是以广播的形式,通知所有在线监听的客户端有新的消息,没有监听的客户端将收不到消息:而queue则 ...
- RabbitMQ入门教程(九):首部交换机Headers
原文:RabbitMQ入门教程(九):首部交换机Headers 版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog ...
- RabbitMQ入门教程(十五):普通集群和镜像集群
原文:RabbitMQ入门教程(十五):普通集群和镜像集群 版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.c ...
- RabbitMQ入门教程(七):主题交换机Topics
原文:RabbitMQ入门教程(七):主题交换机Topics 版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog. ...
- RabbitMQ入门教程(四):工作队列(Work Queues)
原文:RabbitMQ入门教程(四):工作队列(Work Queues) 版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:https:/ ...
- RabbitMQ入门教程(三):Hello World
原文:RabbitMQ入门教程(三):Hello World 版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog. ...
- RabbitMQ入门教程(二):简介和基本概念
原文:RabbitMQ入门教程(二):简介和基本概念 版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn ...
随机推荐
- HDU2082 找单词
问题分析 不难想到用母函数做. 令自变量\(x\)的次数就是单词价值,那么答案就是\(x\)的\(1\)次到\(50\)次的系数之和.由于我们只需要处理前\(51\)项,所以暴力多项式相乘即可. 举个 ...
- 工具类--BeanUtils----Bean转换工具
package com.zhouyy.netBank.util; import java.beans.PropertyDescriptor; import java.lang.reflect.Fiel ...
- JS框架_(Typed.js)彩色霓虹灯发光文字动画
百度云盘 传送门 密码:8oei 发光文字动画效果: <!doctype html> <html> <head> <meta charset="ut ...
- CyclicBarrier源码阅读
一种允许多个线程全部等待彼此都到达某个屏障的同步机制 使用 多个线程并发执行同一个CyclicBarrier实例的await方法时,每个线程执行这个方法后,都会被暂停,只有当最后一个线程执行完awai ...
- Java并发编程之java.util.concurrent包下常见类的使用
一,Condition 一个场景,两个线程数数,同时启动两个线程,线程A数1.2.3,然后线程B数4.5.6,最后线程A数7.8.9,程序结束,这涉及到线程之间的通信. public class Co ...
- 【Spark机器学习速成宝典】模型篇03线性回归【LR】(Python版)
目录 线性回归原理 线性回归代码(Spark Python) 线性回归原理 详见博文:http://www.cnblogs.com/itmorn/p/7873083.html 返回目录 线性回归代码( ...
- shell脚本之awk、sed、grep案例
1.BEGIN END用法user DIR,内容显示用户名称.用户家目录 $NF为awk的内置变量,表示最后一行,$(NF-1)就表示倒数第二行,最后打印页脚 页眉显示 cat /e ...
- defineProperty
### Object.defineProperty() https://segmentfault.com/a/1190000007434923方法会直接在一个对象上定义一个新属性,或者修改一个已经存在 ...
- ceph集群添加osd
获取osd的ID 这个操作是在管理节点上执行 [root@node-4 osd]# ceph osd create 2 对磁盘做处理 [root@node-4 ~]# parted /dev/sdb ...
- apache禁止指定的user_agent访问
user_agent:也就是浏览器标识#禁止指定user_agent <IfModule mod_rewrite.c> RewriteEngine on RewriteCond %{HTT ...