5-RabbitMQ交换机-topic

来源:互联网 发布:程序员app推荐 编辑:程序博客网 时间:2024/06/17 10:29

RabbitMQ交换机-topic

topic交换机

       上次说了direct类型的交换机,这次就说说topic类型的交换机。Direct交换机要求的是绑定键完全匹配后,交换机才会把消息放到队列中,那这样如果我们需要往同一个队列绑定好几个绑定键的时候,就需要绑定好多次了,这样明显不方便。这个时候topic交换机就体现了他的灵活性,可以模糊匹配。绑定的格式还是和之前一样

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

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

下面介绍下模糊匹配的一些特殊字符:

·        *(星)可以替代一个单词。

·        #(哈希)可以替换零个或多个单词。

我们下面举个例子


从图片上我们可以看出我们使用的是topic交换机,绑定键有三个,队列有两个,其中“*.orange.*”绑定键指向的是Q1队列,“*.*.rabbit”“lazy.#”绑定键指向的是Q2队列。

将路由密钥设置为“ quick.orange.rabbit ”的消息将传递给两个队列, “ lazy.orange.elephant ”也会去两个队列。另一方面,“ quick.orange.fox ”只会转到第一个队列,而“ lazy.brown.fox ”只能到第二个队列。“ lazy.pink.rabbit ”比较特殊,即使匹配两个绑定键,但是两个绑定键指向同一个队列,所以这个路由秘钥只转发一次并且传递给同Q2“ quick.brown.fox ”不匹配任何绑定,因此它将被丢弃。

如果我们违反绑定键规则,送一个或四个字的消息,如orange“ quick.orange.male.rabbit ”,会发生什么?那么这些消息将不会匹配任何绑定,并将丢失。

另一方面,“ lazy.orange.male.rabbit ”即使它有四个字,将匹配最后的绑定,并将被传递到第二个队列。

下面是代码的具体实现

生产者

 

package MQ.Exchange.Topic;

 

import java.io.IOException;

import java.util.concurrent.TimeoutException;

 

import com.rabbitmq.client.Channel;

import com.rabbitmq.client.Connection;

import com.rabbitmq.client.ConnectionFactory;

 

/**

 * @Title: MQ.WorkQueues.NewTask.java

 * @Package MQ.WorkQueues

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

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

 * @authoryuanh

 * @date 2017-5-10下午3:50:35

 */

public classNewTask {

   private final static String EXCHANGE_NAME="topic_logs";

   private final static String QUEUE_NAME ="hello_topic";

   private final static String QUEUE_NAME2 ="hello_topic1";

   private final static String[] topicStr =new String[] { "*.orange.*"};

   private final static String[] topicStr2 =new String[] { "*.*.rabbit","lazy.#"};

 

   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,"topic",durable2);

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

      for (String severity :topicStr) {

         channel.queueBind(QUEUE_NAME,EXCHANGE_NAME,severity);

      }

      for (String severity :topicStr2) {

         channel.queueBind(QUEUE_NAME2,EXCHANGE_NAME,severity);

      }

      Stringmessage = "quick.orange.rabbit";

      Stringmessage2 = "lazy.orange.elephant";

      Stringmessage3 = "lazy.pink.rabbit";

      Stringmessage4 = "quick.brown.fox";

      // 将消息放到队列里面

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

      // 将消息放到交换机上

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

      channel.basicPublish(EXCHANGE_NAME,message2,null,message2.getBytes());

      channel.basicPublish(EXCHANGE_NAME,message3,null,message3.getBytes());

      channel.basicPublish(EXCHANGE_NAME,message4,null,message4.getBytes());

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

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

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

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

      // 关闭通道和连接

      channel.close();

      connection.close();

   }

 

 

}

消费者

消费者和之前的一样,只不过是将对列名称改成你需要取的对列名称

 

package MQ.Exchange.Topic;

 

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消息发送到topic的交换机上)

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

 * @authoryuanh

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

 */

public classWorkerResponse {

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

   private final static String QUEUE_NAME ="hello_topic1";

 

   // private final static String QUEUE_NAME2 ="hello_topic1";

 

   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(100);

         }else{

            Thread.sleep(100);

         }

 

      }

   }

}

 

0 0
原创粉丝点击