RabbitMQ实例教程:主题交换机

简介:

  前面的例子中,尽管我们使用了direct路由代替fanout路由解决了盲目广播的问题,但direct路由也有它的缺陷,他不能基于多个标准做路由转发。


  在上面的日志系统中,如果不仅想基于日志等级做订阅,也想根据日志的发生源做订阅该怎么处理呢?这时候你可能想到了unix系统工具中的syslog服务,它不仅基于日志等级(info/warn/crit...)进行路由转发,也会根据操作(auth/cron/kern...)做路由转发。


  如果是那样的话,日志系统就灵活多了,它不仅能够监听来自‘cron’的关键错误,也能监听来自'kern'的所有日志。其实主题交换机(topic exchange)就能解决这种问题。


  主题交换机(Topic exchange)


  主题交换机的路由代码不能是任意写的,必须是小树点分隔开的一组单词列表。这些单词可以随便写,但通常是与连接消息特征有关的单词。有效地路由代码应该是这样的“stock.usd.nyse”,“nyse.vmw”,“quick.orange.rabbit”。路由代码可以随便写,但是长度限制在255字节。


  注意,绑定代码也必须在同一个表单中。topic交换机与direct交换机类似-具有特定路由代码的消息会传送给所有匹配绑定代码的队列,但有两个特殊的绑定代码:


  * :它能替代一个单词 


  #:它能替代0或多个单词

wKiom1YekEyRndmFAABl8iEOXGg312.jpg


  该例子中,我们给所有的动物发送消息,符合由三个单词(第一个单词描述速度;第二个单词描述颜色;第三个单词描述物种)组成的路由代码将会发送消息:“<speed>.<colour>.<species>”。

   

  我们创建了三个绑定:Q1使用“*.orange.*”绑定,Q2使用“*.*.rabbit”和“lazy.#”绑定。这些绑定的意义如下:

  

  Q1描述了所有颜色为橙色的动物。

  

  Q2描述了是兔子的动物和懒惰的动物。

  

  这样,“quick.orange.rabbit”消息通过路由转发给Q1、Q2两个队列。"lazy.orange.elephant"消息也会转发给Q1、Q2两个队列。“quick.orange.fox”消息只会转发给Q1队列,"lazy.brown.fox"也只会转发给Q2队列。"lazy.pink.rabbit"会转发给Q2队列一次,尽管它匹配两个绑定。"quick.brown.fox"并不匹配任何一个队列就会被废弃。

  

  如果我们打破规则,每次只发一个或四个单词的话,如“orange”或”quick.orange.male.rabbit“,这些消息不匹配任何绑定,就会被废弃。但如果发送”lazy.orange.male.rabbit“这样的消息的话,由于它匹配最后的绑定仍会被转发到Q2队列中。

    

  主题交换机是一种非常强大的交换机,当它只绑定”#“时,它会接收所有的消息,与fanout交换机类似。当没有使用”*“和”#“符号时,主题交换机的作用等同与direct交换机。


  源代码


EmitLogTopic.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
package  com.favccxx.favrabbit;
 
import  com.rabbitmq.client.Channel;
import  com.rabbitmq.client.Connection;
import  com.rabbitmq.client.ConnectionFactory;
 
public  class  EmitLogTopic {
 
     private  static  final  String EXCHANGE_NAME =  "topic_logs" ;
 
     public  static  void  main(String[] argv) {
         Connection connection =  null ;
         Channel channel =  null ;
         try  {
             ConnectionFactory factory =  new  ConnectionFactory();
             factory.setHost( "localhost" );
 
             connection = factory.newConnection();
             channel = connection.createChannel();
 
             channel.exchangeDeclare(EXCHANGE_NAME,  "topic" );
 
             String[] routingKeys = {  "fast.orange.duck" "slow.orange.fish" "grey.rabbit" "fast.black.rabbit" ,
                     "quick.white.rabbit" "lazy.dog" "lazy.black.pig"  };
             String[] messages = {  "Hello" "Guys" "Girls" "Babies"  };
 
             for  ( int  i =  0 ; i < routingKeys.length; i++) {
                 for  ( int  j =  0 ; j < messages.length; j++) {
                     channel.basicPublish(EXCHANGE_NAME, routingKeys[i],  null , messages[j].getBytes( "UTF-8" ));
                     System.out.println( " [x] Sent '"  + routingKeys[i] +  "':'"  + messages[j] +  "'" );
                 }
             }
         catch  (Exception e) {
             e.printStackTrace();
         finally  {
             if  (connection !=  null ) {
                 try  {
                     connection.close();
                 catch  (Exception ignore) {
                 }
             }
         }
     }
}


ReceiveLogsTopic.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
package  com.favccxx.favrabbit;
 
import  java.io.IOException;
 
import  com.rabbitmq.client.AMQP;
import  com.rabbitmq.client.Channel;
import  com.rabbitmq.client.Connection;
import  com.rabbitmq.client.ConnectionFactory;
import  com.rabbitmq.client.Consumer;
import  com.rabbitmq.client.DefaultConsumer;
import  com.rabbitmq.client.Envelope;
 
public  class  ReceiveLogsTopic {
 
     private  static  final  String EXCHANGE_NAME =  "topic_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,  "topic" );
         String queueName = channel.queueDeclare().getQueue();
 
         String[] bindingKeys = {  "*.orange.*" "*.*.rabbit" "lazy.#"  };
         for  ( final  String bindingKey : bindingKeys) {
             channel.queueBind(queueName, EXCHANGE_NAME, bindingKey);
             Consumer consumer =  new  DefaultConsumer(channel) {
                 @Override
                 public  void  handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties,
                         byte [] body)  throws  IOException {
                     String message =  new  String(body,  "UTF-8" );
                     System.out.println( "["  + bindingKey +  "] Received message :'"  + message +  "' from routingKey : "  + envelope.getRoutingKey());
                 }
             };
             channel.basicConsume(queueName,  true , consumer);
         }
 
     }
}


运行消息发送器,在消息接收平台输出内容如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
[*.orange.*] Received message : 'Hello'  from routingKey : fast.orange.duck
[*.*.rabbit] Received message : 'Guys'  from routingKey : fast.orange.duck
[lazy. #] Received message :'Girls' from routingKey : fast.orange.duck
[*.orange.*] Received message : 'Babies'  from routingKey : fast.orange.duck
[*.*.rabbit] Received message : 'Hello'  from routingKey : slow.orange.fish
[lazy. #] Received message :'Guys' from routingKey : slow.orange.fish
[*.orange.*] Received message : 'Girls'  from routingKey : slow.orange.fish
[*.*.rabbit] Received message : 'Babies'  from routingKey : slow.orange.fish
[lazy. #] Received message :'Hello' from routingKey : fast.black.rabbit
[*.orange.*] Received message : 'Guys'  from routingKey : fast.black.rabbit
[*.*.rabbit] Received message : 'Girls'  from routingKey : fast.black.rabbit
[lazy. #] Received message :'Babies' from routingKey : fast.black.rabbit
[*.orange.*] Received message : 'Hello'  from routingKey : quick.white.rabbit
[*.*.rabbit] Received message : 'Guys'  from routingKey : quick.white.rabbit
[lazy. #] Received message :'Girls' from routingKey : quick.white.rabbit
[*.orange.*] Received message : 'Babies'  from routingKey : quick.white.rabbit
[*.*.rabbit] Received message : 'Hello'  from routingKey : lazy.dog
[lazy. #] Received message :'Guys' from routingKey : lazy.dog
[*.orange.*] Received message : 'Girls'  from routingKey : lazy.dog
[*.*.rabbit] Received message : 'Babies'  from routingKey : lazy.dog
[lazy. #] Received message :'Hello' from routingKey : lazy.black.pig
[*.orange.*] Received message : 'Guys'  from routingKey : lazy.black.pig
[*.*.rabbit] Received message : 'Girls'  from routingKey : lazy.black.pig
[lazy. #] Received message :'Babies' from routingKey : lazy.black.pig




本文转自 genuinecx 51CTO博客,原文链接:http://blog.51cto.com/favccxx/1703031,如需转载请自行联系原作者
相关实践学习
RocketMQ一站式入门使用
从源码编译、部署broker、部署namesrv,使用java客户端首发消息等一站式入门RocketMQ。
消息队列 MNS 入门课程
1、消息队列MNS简介 本节课介绍消息队列的MNS的基础概念 2、消息队列MNS特性 本节课介绍消息队列的MNS的主要特性 3、MNS的最佳实践及场景应用 本节课介绍消息队列的MNS的最佳实践及场景应用案例 4、手把手系列:消息队列MNS实操讲 本节课介绍消息队列的MNS的实际操作演示 5、动手实验:基于MNS,0基础轻松构建 Web Client 本节课带您一起基于MNS,0基础轻松构建 Web Client
目录
相关文章
|
27天前
|
物联网
MQTT常见问题之用单片机接入阿里MQTT实例失败如何解决
MQTT(Message Queuing Telemetry Transport)是一个轻量级的、基于发布/订阅模式的消息协议,广泛用于物联网(IoT)中设备间的通信。以下是MQTT使用过程中可能遇到的一些常见问题及其答案的汇总:
|
27天前
|
消息中间件 弹性计算 物联网
MQTT常见问题之发布MQTT主题消息失败如何解决
MQTT(Message Queuing Telemetry Transport)是一个轻量级的、基于发布/订阅模式的消息协议,广泛用于物联网(IoT)中设备间的通信。以下是MQTT使用过程中可能遇到的一些常见问题及其答案的汇总:
|
3月前
|
消息中间件 JSON 缓存
RabbitMQ快速学习之WorkQueues模型、三种交换机、消息转换器(SpringBoot整合)
RabbitMQ快速学习之WorkQueues模型、三种交换机、消息转换器(SpringBoot整合)
|
9天前
|
消息中间件 微服务
RabbitMQ入门指南(四):交换机与案例解析
RabbitMQ是一个高效、可靠的开源消息队列系统,广泛用于软件开发、数据传输、微服务等领域。本文主要介绍了交换机在RabbitMQ中的作用与类型、交换机案例(Fanout交换机、Direct交换机、Topic交换机)等内容。
17 0
|
28天前
|
消息中间件 Linux 开发工具
Linux系统安装RabbitMQ详细教程
Linux系统安装RabbitMQ详细教程
19 0
|
1月前
|
消息中间件 存储 Cloud Native
【Spring云原生系列】Spring RabbitMQ:异步处理机制的基础--消息队列 原理讲解+使用教程
【Spring云原生系列】Spring RabbitMQ:异步处理机制的基础--消息队列 原理讲解+使用教程
|
2月前
|
消息中间件 算法 微服务
升华 RabbitMQ:解锁一致性哈希交换机的奥秘【RabbitMQ 十】
升华 RabbitMQ:解锁一致性哈希交换机的奥秘【RabbitMQ 十】
35 0
|
3月前
|
消息中间件 Java Spring
RabbitMQ各种模式的含义与Spring Boot实例详解
RabbitMQ各种模式的含义与Spring Boot实例详解
36 0
|
3月前
|
消息中间件 存储
RabbitMQ之交换机
【1月更文挑战第9天】 RabbitMQ 消息传递模型的核心思想是: 生产者生产的消息从不会直接发送到队列。实际上,通常生产者甚至都不知道这些消息传递传递到了哪些队列中。 相反,生产者只能将消息发送到交换机(exchange),交换机工作的内容非常简单,一方面它接收来自生产者的消息,另一方面将它们推入队列。交换机必须确切知道如何处理收到的消息。是应该把这些消息放到特定队列还是说把他们到许多队列中还是说应该丢弃它们。这就的由交换机的类型来决定。
132 1

热门文章

最新文章