3-RabbitMQ交换机- fanout

RabbitMQ交换机- fanout

交换机

RabbitMQ中的消息传递模型的核心思想是,生产者从不将任何消息直接发送到队列。实际上,生产者通常甚至不知道是否将消息传递到任何队列。

相反,生产者只能将信息发送到交换机。交换是一件非常简单的事情。一方面,它收到来自生产者的消息,另一方将它们推送到队列。交换机必须准确知道接收到的消息如何处理。应该附加到特定队列吗?应该附加到很多队列吗?或者应该丢弃。其规则由交换类型定义 

下面我就介绍下fanout类型的交换机。

Fanout

Fanout交换机的交换非常简单,就是将你收到的消息广播到所有知道的队列。

3-RabbitMQ交换机- fanout_第1张图片
当一个消费者对应一个交换机的时候,我们可以实现消费者共享这个消息,下面是代码

生产者

交换机绑定队列既可以在生产者中实现,也可以在消费者中实现,此次我是在生产者中绑定了两个队列,再构造两个消费者与队列相对应

绑定


绑定代码:

      //将队列绑定到交换机上

      channel.queueBind(QUEUE_NAME,EXCHANGE_NAME,"");

      channel.queueBind(QUEUE_NAME2,EXCHANGE_NAME,"");

生产者代码如下:

package MQ.Exchange.Fanout;

 

import java.io.IOException;

import java.util.concurrent.TimeoutException;

 

import com.rabbitmq.client.Channel;

import com.rabbitmq.client.Connection;

importcom.rabbitmq.client.ConnectionFactory;

public classNewTask {

   private final static String EXCHANGE_NAME="logs";

   private final static String QUEUE_NAME ="hello_fanout2";

   private final static String QUEUE_NAME2 ="hello_fanout3";

 

   public static void main(String[] args)throws IOException,TimeoutException {

      // 创建连接连接到MabbitMQ

      ConnectionFactoryfactory = newConnectionFactory();

      // 设置MabbitMQ所在主机ip或者主机名

      factory.setHost("127.0.0.1");

      factory.setUsername("yuanh");

      factory.setPassword("yuanh");

      factory.setPort(5672);

      factory.setVirtualHost("y_yuanh");

      Connectionconnection = factory.newConnection();

      // 创建一个频道

      Channelchannel = connection.createChannel();

      // 声明队列、设置队列持久化

      boolean durable =true;

      channel.queueDeclare(QUEUE_NAME, durable,false,false,null);

      channel.queueDeclare(QUEUE_NAME2, durable,false,false,null);

      // 声明fanout交换机、设置持久化

      boolean durable2 =true;

      channel.exchangeDeclare(EXCHANGE_NAME,"fanout",durable2);

      //将队列绑定到交换机上

      channel.queueBind(QUEUE_NAME,EXCHANGE_NAME,"");

      channel.queueBind(QUEUE_NAME2,EXCHANGE_NAME,"");

      Stringmessage = getMessage(args);

      // 将消息放到队列里面

      // channel.basicPublish("", QUEUE_NAME, null,message.getBytes());

      // 将消息放到交换机上

      channel.basicPublish(EXCHANGE_NAME,"",null,message.getBytes());

      System.out.println("发送 '" + message +"'");

      // 关闭通道和连接

      channel.close();

      connection.close();

   }

 

   private static StringgetMessage(String[] strings) {

      if (strings.length < 1)

         return"Hello World..!";

      return joinStrings(strings," ");

   }

 

   private static StringjoinStrings(String[] strings, String delimiter) {

      int length = strings.length;

      if (length == 0)

         return"";

      StringBuilderwords = newStringBuilder(strings[0]);

      for (int i = 1; i < length;i++) {

         words.append(delimiter).append(strings[i]);

      }

      return words.toString();

   }

 

}

消费者

让各个队列对应一个消费者,进行消费

3-RabbitMQ交换机- fanout_第2张图片
消费者代码如下:

package MQ.Exchange.Fanout;

 

import com.rabbitmq.client.Channel;

import com.rabbitmq.client.Connection;

import com.rabbitmq.client.ConnectionFactory;

import com.rabbitmq.client.QueueingConsumer;

 

@SuppressWarnings("deprecation")

/**

 * @Title: MQ.WorkQueues.Worker.java

 * @Package MQ.WorkQueues

 * @Description:TODO(MQ消息发送到fanout的交换机上)

 * @Copyright: Copyright (c) 2017 YUANH All Rights Reserved

 * @authoryuanh

 * @date 2017-5-10下午3:48:59

 */

public classWorkerResponse {

   private final static String QUEUE_NAME ="hello_fanout2";

   //private final static String QUEUE_NAME ="hello_fanout3";

   // private final static String EXCHANGE_NAME ="logs";

 

   public static void main(String[] argv)throws Exception {

 

      // 创建连接连接到MabbitMQ

      ConnectionFactoryfactory = newConnectionFactory();

      // 设置MabbitMQ所在主机ip或者主机名

      factory.setHost("127.0.0.1");

      factory.setUsername("yuanh");

      factory.setPassword("yuanh");

      factory.setPort(5672);

      factory.setVirtualHost("y_yuanh");

      Connectionconnection = factory.newConnection();

      Channelchannel = connection.createChannel();

      // 1声明队列、设置队列持久化

      boolean durable =true;

      channel.queueDeclare(QUEUE_NAME, durable,false,false,null);

      QueueingConsumerconsumer = newQueueingConsumer(channel);

      // 2消费者指定消费队列,打开应答机制,注意false才是打开手动应对,true为自动应答

      boolean ack =false;

      channel.basicConsume(QUEUE_NAME, ack, consumer);

      // 3消费者设置最大服务转发消息数量,公平转发

      int prefetchCount = 1;

      channel.basicQos(prefetchCount);

      try {

         while (true) {

            QueueingConsumer.Deliverydelivery = consumer.nextDelivery();

            Stringmessage = newString(delivery.getBody());

            System.out.println("接收 '" + message +"'");

            try {

                doWork(message);

            }finally{

                System.out.println("结束");

                // 另外需要在每次处理完成一个消息后,手动发送一次应答(ack=false)

                channel.basicAck(delivery.getEnvelope().getDeliveryTag(),

                      false);

            }

         }

      }catch(Exception e) {

         channel.close();

         connection.close();

      }

   }

 

   private static void doWork(String task)throws InterruptedException {

      for (char ch : task.toCharArray()){

         if (ch =='.')

            Thread.sleep(1000);

      }

   }

}

 

你可能感兴趣的:(RabbitMQ)