- RabbitMQ教程3:一个消息发给多个消费者
- 代码基础: 易学笔记-RabbitMQ教程1:一个生产者和一个消费者
- 错误的消息队列模型
- 生产者:发送消息的用户程序
- 队列:存储消息的缓冲区
- 消费者:接收消息的用户程序
- 正确的队列模型
- 生产者:发送消息的用户程序
- 交换器:存储消息的缓冲区,生产者从交换器中发布消息
- 队列:接受交换器中消息的一个中介
- 消费者:接收消息的用户程序
- 交换器(路由器):Exchange:
- 类型:
- direct
- topic
- headers
- fanout
- 往交换器中
- 匿名Exchange: channel.basicPublish("",第一个参数为空则为匿名Exchange
- 类型:
- 临时队列
- 概念:不指定名称的队列,临时又系统自动生成队列名称
- 用处:为了接收某个Exchange所有的消息
- 交换器和队列的绑定
- 交换器一定在生产者声明,而队列可以在生产者定义,也可以在消费者定义
- 绑定:也就是队列从交换器中获取消息
- 新建生产者:
package oneProductAllConsume; import com.rabbitmq.client.BuiltinExchangeType; import com.rabbitmq.client.ConnectionFactory; import com.rabbitmq.client.Connection; import com.rabbitmq.client.Channel; public class ExchangesProductSend { private static final String EXCHANGE_NAME = "logs"; public static void main(String[] argv) throws Exception { // 建立连接和通道 ConnectionFactory factory = new ConnectionFactory(); factory.setHost("localhost"); Connection connection = factory.newConnection(); Channel channel = connection.createChannel(); /** * 声明路由以及路由的类型 */ channel.exchangeDeclare(EXCHANGE_NAME, BuiltinExchangeType.FANOUT); String message = "msg..."; /** * 这里没有指明队列,队列由消费者指定 */ /** * 发布消息 * 这里的消息发布到EXCHANGE,再有EXCHANGE发布到队列 */ channel.basicPublish(EXCHANGE_NAME, "", null, message.getBytes("UTF-8")); System.out.println(" [x] Sent '" + message + "'"); // 关闭连接和通道 channel.close(); connection.close(); } }
-
* 定义 EXCHANGE名称
*/
private static final String EXCHANGE_NAME = "logs";
- 声明交换器类型
/**
* 声明路由以及路由的类型
*/
channel.exchangeDeclare(EXCHANGE_NAME, BuiltinExchangeType.FANOUT);
- 往交换器中发布消息
/**
* 这里没有指明队列,队列由消费者指定
*/
/**
* 发布消息
* 这里的消息发布到指定的EXCHANGE(logs),再由EXCHANGE发布到队列
*/
channel.basicPublish(EXCHANGE_NAME, "", null, message.getBytes("UTF-8"));
-
- 新建消费者:RandomQueueConsumeRecv.java
-
/**
* 定义 EXCHANGE名称
*/
private static final String EXCHANGE_NAME = "logs";
- 声明交换器类型,要求要与生产者一致
/**
* 声明路由以及路由的类型
*/
channel.exchangeDeclare(EXCHANGE_NAME, BuiltinExchangeType.FANOUT);
- 声明随机队列
/**
* 声明一个随机名字的队列
*/
String queueName = channel.queueDeclare().getQueue();
- 交换器和队列绑定
/**
* 绑定队列到路由器上
*/
channel.queueBind(queueName, EXCHANGE_NAME, "");
- 定义消费对象以及从队列上获取消息:和原来的一样
-
- 测试:
- 先启动两个消费者
- 消费者一:
- 消费者二:
- 启动生产者
- 消费者接受到生产者所有消息
- 先启动两个消费者