• rabbitMQ_topic(五)


     

    主题转发器

    发送到主题转发器的消息不能有任意的 routing_key - 它必须是由点分隔的单词列表。这些单词可以是任何东西,但通常它们指定与消息相关联的一些功能。几个有效的routeKey示例:“ stock.usd.nyse”,“ nyse.vmw ”,“ quick.orange.rabbit ”。routeKey中可以有任意多的单词,最多可达255个字节。

    绑定键(即绑定时使用的routeKey)也必须是相同的形式。topics转发器可以是用通配符:

    • *(星)可以替代一个单词。
    • #(哈希)可以替换零个或多个单词。

    如下图:

    在这个例子中,我们将发送所有描述动物的消息。消息将使用由三个字(两个点)组成的routeKey发送。routeKey中的第一个单词将描述速度,第二个描述颜色,第三个描述种类( <speed>.<color>.<species>)。

    我们创建了三个绑定:Q1队列绑定键* .orange.*,Q2绑定键*.*.rabbit和lazy.#。

    这些绑定可以总结为:

    • Q1对所有的橙色动物感兴趣。
    • Q2想听听有关兔子的一切,以及关于懒惰动物的一切。

    将routeKey设置为“ quick.orange.rabbit ”的消息将传递给两个队列。消息“ lazy.orange.elephant ”也会传递给两个队列。“ quick.orange.fox ”只会转到第一个队列,而“ lazy.brown.fox ”只能到第二个队列。“ lazy.pink.rabbit ”将被传递到第二个队列。“ quick.brown.fox ”不匹配任何绑定,因此它将被丢弃。

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

    但是在某种情况下,如“ lazy.orange.male.rabbit ”即使它有四个单词,却会匹配最后的绑定,并将消息传递到第二个队列。

    主题转发器

    主题转发是强大的,其他转发器能做到的事情,它也能做到。

    当队列与“ # ”(哈希)绑定键绑定时,它将接收所有消息,而不管绑定键是什么,就像fanout转发器一样

    当特殊字符“ * ”(星号)和“ # ”(哈希)在绑定中不被使用时,主题转发器将表现得像一个直接转发器。

    完整示例

    EmitLogTopic.java的代码:

     1 package com.rabbitMQ;
     2 
     3 import com.rabbitmq.client.Channel;
     4 import com.rabbitmq.client.Connection;
     5 import com.rabbitmq.client.ConnectionFactory;
     6 
     7 public class EmitLogTopic {
     8 
     9     private static final String EXCHANGE_NAME = "topic_logs";
    10 
    11     public static void main(String[] argv)
    12                   throws Exception {
    13 
    14         ConnectionFactory factory = new ConnectionFactory();
    15         factory.setHost("localhost");
    16         Connection connection = factory.newConnection();
    17         Channel channel = connection.createChannel();
    18 
    19         channel.exchangeDeclare(EXCHANGE_NAME, "topic");
    20 
    21         String routingKey = getRouting(argv);
    22         String message = getMessage(argv);
    23 
    24         channel.basicPublish(EXCHANGE_NAME, routingKey, null, message.getBytes());
    25         System.out.println(" [x] Sent '" + routingKey + "':'" + message + "'");
    26 
    27         connection.close();
    28     }
    29    
    30     
    31     private static String getRouting(String[] argv) {
    32 
    33         if (argv.length == 0) {
    34 
    35             return "jr;;p.critical";
    36         }
    37         String str = argv[0];
    38 
    39         String routeKey = str.replaceAll("=.*", "");
    40 
    41         return routeKey;
    42     }
    43 
    44     private static String getMessage(String[] argv) {
    45         if (argv.length == 0) {
    46 
    47             return "I like play game.";
    48         }
    49         String str = argv[0];
    50         String message = str.replaceAll(".*=", "");
    51         return message;
    52     }
    53 
    54     
    55 }

    ReceiveLogsTopic.java的代码:

     1 package com.rabbitMQ;
     2 
     3 import java.io.IOException;
     4 
     5 import com.rabbitmq.client.AMQP;
     6 import com.rabbitmq.client.Channel;
     7 import com.rabbitmq.client.Connection;
     8 import com.rabbitmq.client.ConnectionFactory;
     9 import com.rabbitmq.client.Consumer;
    10 import com.rabbitmq.client.DefaultConsumer;
    11 import com.rabbitmq.client.Envelope;
    12 
    13 public class ReceiveLogsTopic {
    14   private static final String EXCHANGE_NAME = "topic_logs";
    15 
    16   public static void main(String[] argv) throws Exception {
    17     ConnectionFactory factory = new ConnectionFactory();
    18     factory.setHost("localhost");
    19     Connection connection = factory.newConnection();
    20     Channel channel = connection.createChannel();
    21 
    22     channel.exchangeDeclare(EXCHANGE_NAME, "topic");
    23     String queueName = channel.queueDeclare().getQueue();
    24 
    25     if (argv.length < 1) {
    26       System.err.println("Usage: ReceiveLogsTopic [binding_key]...");
    27       System.exit(1);
    28     }
    29 
    30     for (String bindingKey : argv) {
    31       channel.queueBind(queueName, EXCHANGE_NAME, bindingKey);
    32     }
    33 
    34     System.out.println(" [*] Waiting for messages. To exit press CTRL+C");
    35 
    36     Consumer consumer = new DefaultConsumer(channel) {
    37       @Override
    38       public void handleDelivery(String consumerTag, Envelope envelope,
    39                                  AMQP.BasicProperties properties, byte[] body) throws IOException {
    40         String message = new String(body, "UTF-8");
    41         System.out.println(" [x] Received '" + envelope.getRoutingKey() + "':'" + message + "'");
    42         System.out.println(consumerTag);//amq.ctag-yqB24qMf7hEtpyZgR1p4MQ
    43         System.out.println(properties);//#contentHeader<basic>(content-type=null, content-encoding=null, headers=null, delivery-mode=null, priority=null, correlation-id=null, reply-to=null, expiration=null, message-id=null, timestamp=null, type=null, user-id=null, app-id=null, cluster-id=null)
    44         System.out.println(envelope);//Envelope(deliveryTag=1传送标志, redeliver=false重新传送, exchange=topic_logs转发器名称, routingKey=jr;;p.critical)
    45       }
    46     };
    47     channel.basicConsume(queueName, true, consumer);
    48   }
    49 }

    启动ReceiveLogsTopic.java,给它传*.error

    启动ReceiveLogsTopic.java,给它传*.info

    启动EmitLogTopic.java,给它传#=all matches

    结果:俩个ReceiveLogsTopic.java会收到all matches

    启动ReceiveLogsTopic.java,给它传mistake=error

    只有第一个ReceiveLogsTopic.java收到消息

  • 相关阅读:
    什么是内部类
    "=="和equals方法究竟有什么区别?
    SWFUpload乱码问题的解决
    xStream转换XML、JSON
    Java文件下载
    笔记摘录
    Javascript 函数传参问题
    JQUERY伸缩导航
    ruby关于flip-flop理解上一个注意点
    ruby 使用Struct场景
  • 原文地址:https://www.cnblogs.com/honger/p/6964053.html
Copyright © 2020-2023  润新知