前面都是一条消息只会被一个消费者处理。

如果要每个消费者都处理同一个消息,rabbitMq也提供了相应的方法。

在以前的程序中,不管是生产者端还是消费者端都必须知道一个指定的QueueName才能发送、获取消息。  而rabbitMQ消息模型的核心思想是生产者不会将消息直接发送给队列。

因为,生产者通常不会知道消息将会被哪些消费者接收。

生产者的消息虽然不是直接发送给Queue,但是消息会交给Exchange,所以需要定义Exchange的消息分发模式 ,之前的程序中,有如下一行代码:

channel.basicPublish("", queueName , null , msg.getBytes());

第一个参数为空字符串,其实第一个参数就是ExchangeName,这里用空字符串,就表示消息会交给默认的Exchange。

下面我们将自己定义Exchange的属性。

Sender04.java

 package com.zf.rabbitmq04;

 import java.io.IOException;

 import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory; /**
* 发送消息
* @author zhoufeng
*
*/
public class Sender04 { public static void main(String[] args) throws IOException { ConnectionFactory connFac = new ConnectionFactory() ; //RabbitMQ-Server安装在本机,所以直接用127.0.0.1
connFac.setHost("127.0.0.1"); //创建一个连接
Connection conn = connFac.newConnection() ; //创建一个渠道
Channel channel = conn.createChannel() ; //定义ExchangeName,第二个参数是Exchange的类型,fanout表示消息将会分列发送给多账户
String exchangeName = "news" ;
channel.exchangeDeclare(exchangeName, "fanout") ; String msg = "Hello World!"; //发送消息,这里与前面的不同,这里第一个参数不再是字符串,而是ExchangeName ,第二个参数也不再是queueName,而是空字符串
channel.basicPublish( exchangeName , "" , null , msg.getBytes()); System.out.println("send message[" + msg + "] to exchange "+ exchangeName +" success!"); channel.close();
conn.close(); } }

Send04.java 发送消息时没有指定的queueName 用的空字符串代替的。 Exchange的类型有direct, topic, headers 、 fanout四种,上面用的是fanout类型

 package com.zf.rabbitmq04;

 import java.io.IOException;

 import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.ConsumerCancelledException;
import com.rabbitmq.client.QueueingConsumer;
import com.rabbitmq.client.QueueingConsumer.Delivery;
import com.rabbitmq.client.ShutdownSignalException; /**
* 接收消息
* @author zhoufeng
*
*/
public class Recv04_01 { public static void main(String[] args) throws IOException, ShutdownSignalException, ConsumerCancelledException, InterruptedException { ConnectionFactory connFac = new ConnectionFactory() ; connFac.setHost("127.0.0.1"); Connection conn = connFac.newConnection() ; Channel channel = conn.createChannel() ; String exchangeName = "news" ;
channel.exchangeDeclare(exchangeName, "fanout") ; //这里使用没有参数的queueDeclare方法创建Queue并获取QueueName
String queueName = channel.queueDeclare().getQueue() ; //将queue绑定到Exchange中
channel.queueBind( queueName, exchangeName, "") ; //配置好获取消息的方式
QueueingConsumer consumer = new QueueingConsumer(channel) ;
channel.basicConsume(queueName, true, consumer) ; //循环获取消息
while(true){ //获取消息,如果没有消息,这一步将会一直阻塞
Delivery delivery = consumer.nextDelivery() ; String msg = new String(delivery.getBody()) ; System.out.println("received message[" + msg + "] from " + queueName);
} } }

Recv04_01.java  使用channel.queueDeclare()方法创建了一个Queue,该Queue有系统创建,并分配了一个随机的名称。 然后将该Queue与与Exchange绑定在一起。 该Queue就能从Exchange中后去消息了。

测试

将Recv04_01.java 文件复制几份 Recv04_02.java   Recv04_03.java

然后执行Recv04_01 与 Recv04_02

接下来执行Sender04发送消息,可以看到Recv04_01 与Recv04_02都接收到了消息。

然后执行Recv04_03,没有获取到任何消息。

接下来再执行Sender04发送消息,可以看到Recv04_01 、Recv04_02与Recv04_03都接收到了消息。

说明Exchange在收到生产者的消息后,会将消息发送给当前已经与它绑定了的所有Queue 。  然后被移除。

rabbitMQ学习笔记(四) 发布/订阅消息的更多相关文章

  1. RabbitMQ入门学习系列(四) 发布订阅模式

    发布订阅模式 什么时发布订阅模式 把消息发送给多个订阅者.也就是有多个消费端都完整的接收生产者的消息 换句话说 把消息广播给多个消费者 消息模型的核心 RabbitMQ不发送消息给队列,生产者也不知道 ...

  2. Redis学习笔记8--Redis发布/订阅

    发布订阅(pub/sub)是一种消息通信模式,主要的目的是解耦消息发布者和消息订阅者之间的耦合,这点和设计模式中的观察者模式比较相似.pub /sub不仅仅解决发布者和订阅者直接代码级别耦合也解决两者 ...

  3. Redis学习笔记(8)-发布/订阅

    package cn.com; import java.util.List; import redis.clients.jedis.Jedis; public class Redis_PubSub { ...

  4. rabbitMQ学习笔记(六) topic类型消息。

    上一节中使用了消息路由,消费者可以选择性的接收消息. 但是这样还是不够灵活. 比如某个消费者要订阅娱乐新闻消息 . 包括新浪.网易.腾讯的娱乐新闻.那么消费者就需要绑定三次,分别绑定这三个网站的消息类 ...

  5. RabbitMQ学习笔记四:RabbitMQ命令(附疑难问题解决)

    本来今天是想做RabbitMQ之优先级队列的,但是,在RabbitMQ Server创建queue时,增加优先级的最大值,头脑发热写了9999999,导致电脑内存直接飙到100%,只能重启电脑,并卸载 ...

  6. RabbitMQ学习笔记五:RabbitMQ之优先级消息队列

    RabbitMQ优先级队列注意点: 1.只有当消费者不足,不能及时进行消费的情况下,优先级队列才会生效 2.RabbitMQ3.5以后才支持优先级队列 代码在博客:RabbitMQ学习笔记三:Java ...

  7. RabbitMQ学习笔记(五) Topic

    更多的问题 Direct Exchange帮助我们解决了分类发布与订阅消息的问题,但是Direct Exchange的问题是,它所使用的routingKey是一个简单字符串,这决定了它只能按照一个条件 ...

  8. 官网英文版学习——RabbitMQ学习笔记(一)认识RabbitMQ

    鉴于目前中文的RabbitMQ教程很缺,本博主虽然买了一本rabbitMQ的书,遗憾的是该书的代码用的不是java语言,看起来也有些不爽,且网友们不同人学习所写不同,本博主看的有些地方不太理想,为此本 ...

  9. rabbitmq学习(九) —— 关于消息队列的选型

    转自http://cmsblogs.com/?p=3846 在IM这种讲究高并发.高消息吞吐的互联网场景下,MQ消息中间件是个很重要的基础设施,它在IM系统的服务端架构中担当消息中转.消息削峰.消息交 ...

随机推荐

  1. ZOJ 1654--Place the Robots【二分匹配 && 经典建图】

    Place the Robots Time Limit: 5 Seconds      Memory Limit: 32768 KB Robert is a famous engineer. One ...

  2. Codeforces Round #313 (Div. 2)(A,B,C,D)

    A题: 题目地址:Currency System in Geraldion 题意:给出n中货币的面值(每种货币有无数张),要求不能表示出的货币的最小值.若全部面值的都能表示,输出-1. 思路:水题,就 ...

  3. Huffman编码实现压缩解压缩

    这是我们的课程中布置的作业.找一些资料将作业完毕,顺便将其写到博客,以后看起来也方便. 原理介绍 什么是Huffman压缩 Huffman( 哈夫曼 ) 算法在上世纪五十年代初提出来了,它是一种无损压 ...

  4. MFC画标尺

    void CJjjView::OnPaint() { CPaintDC dc(this); //屏幕初始化 dc.SetMapMode(MM_LOENGLISH);//0.01in ;1英寸映射 dc ...

  5. luogu1908 逆序对 树状数组

    题目大意:对于给定的一段正整数序列,逆序对就是序列中ai>aj且i<j的有序对.求一段序列的逆序对数. 对于一个数组T,其一个点的值为值与该点下标相等的A序列中点的个数.对T维护一个树状数 ...

  6. bzoj5029: 贴小广告&&bzoj5168: [HAOI2014]贴海报

    以后做双精题请至少先跑个数据...输入都不一样... 做法就是离散化大力线段树. 记得在x+1和y-1插点 看这个数据: 1000 121 10050 8080 9950 981 56100 2002 ...

  7. 写个js 分页玩玩(原创)

    <ul id="page"> <li class="pagetest">1</li> <li class=" ...

  8. [HTML5] 让IE支持HTML5的方法

    越来越多的站点开始使用 HTML5 标签,但是目前的情况是还有很多人在使用IE6.IE7.IE8.为了让所有浏览者都可以正常的访问,解决方案有下面两个: 1.为网站创建多套模板,通过程序对User-A ...

  9. Python基本数据类型之字符串str

    字符串 定义:它是一个有序的字符的集合,用于存储和表示基本的文本信息,‘’或“”或‘’‘ ’‘’中间包含的内容称之为字符串 字符串的结构类型为'...' "..." "' ...

  10. 开发辅助 | 阿里图标库iconfont入门使用

    目前大多数的互联网公司,前端开发和UI设计师配合中,针对设计师给图的效果图,前端开发工程师不再像往常一样对于细小图标进行切图,取而代之的是引用阿里图标库(http://iconfont.cn/):简单 ...