1、简介
在上篇教程中,我们搭建了一个工作队列,每个任务只分发给一个工作者,在本篇教程中,我们要做的跟之前完全不一样 —— 分发一个消息给多个消费者(consumers)。这种模式被称为“发布/订阅”。
2、交换机Exchanges
RabbitMQ消息模型的核心理念是:发布者(producer)只需要把消息发送给一个交换机(exchange)。交换机一边从发布者方接收消息,一边把消息推送到队列。交换机必须知道如何处理它接收到的消息,是应该推送到指定的队列还是是多个队列,或者是直接忽略消息。这些规则是通过交换机类型(exchange type)来定义的。
可供选择的交换机类型:
- 直连交换机(direct)
- 主题交换机(topic)
- (头交换机)headers
- 扇型交换机(fanout)
这里我们选择使用扇形交换机,它会把消息发送给它所知道的所有队列。
3、发送消息
1 Connection connection = factory.newConnection(); 2 Channel channel = connection.createChannel(); 3 4 channel.exchangeDeclare("logs", "fanout"); 5 6 channel.basicPublish("logs", "", null, message.getBytes()); 7 System.out.println("发送消息:" + message); 8 9 channel.close(); 10 connection.close();
4、接收消息
在消息的接收方我们也要进行一些操作:
(1)当我们连接上RabbitMQ的时候,我们需要一个全新的、空的队列。我们可以手动创建一个随机的队列名,或者让服务器为我们选择一个随机的队列名(推荐)。
(2)将交换机和队列进行绑定,告诉交换机如何将消息发送到我们的队列
在进行上面2个操作过后,我们就可以接收到消息了:
1 Connection connection = factory.newConnection(); 2 Channel channel = connection.createChannel(); 3 4 channel.exchangeDeclare("logs", "fanout"); 5 String queueName = channel.queueDeclare().getQueue(); // 创建一个临时空队列 6 channel.queueBind(queueName, "logs", ""); // 将交换机和队列进行绑定,告诉交换机将消息发送到我们的队列中 7 8 Consumer consumer = new DefaultConsumer(channel) { 9 @Override 10 public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException { 11 String message = new String(body, "UTF-8"); 12 13 System.out.println("接收到消息:" + message); 14 } 15 }; 16 channel.basicConsume(queueName, true, consumer);
5、测试
当发送1条消息过后,所有绑定的接收者都可以接收到发送的数据。