1.概述
1.1 话题交流
发送到topic 交换的消息不能具有任意的 routing_key它必须是单词列表,以点分隔。这些词可以是任何东西,但通常它们指定与消息相关的某些功能。一些有效的路由关键示例:“ stock.usd.nyse ”,“ nyse.vmw ”,“ quick.orange.rabbit ”。路由密钥中可以包含任意多个单词,最多255个字节。
绑定密钥还必须采用相同的形式。主题交换背后的逻辑类似于直接交换的逻辑 -使用特定路由密钥发送的消息将传递到所有使用匹配绑定密钥绑定的队列。但是,绑定键有两个重要的特殊情况:
- *(星号)可以代替一个单词。
- #(哈希)可以替代零个或多个单词。
在此示例中,我们将发送所有描述动物的消息。将使用包含三个词(两个点)的路由密钥发送消息。路由键中的第一个单词将描述速度,第二个描述颜色,第三个描述物种。我们创建了三个绑定:Q1与绑定键“ * .orange.* ” 绑定,Q2与“ *.*.rabbit ”和“ lazy.# ” 绑定。
这些绑定可以总结为:
Q1对所有orange都感兴趣。
Q12想听听有关rabbit的一切,以及有关lazy的一切。
话题交流
主题交流功能强大,可以像其他交流一样进行。
当一个队列用“ # ”(哈希)绑定键绑定时,它将接收所有消息,而与路由键无关,就像在扇出交换中一样。
当在绑定中不使用特殊字符“ * ”(星号)和“ # ”(哈希)时,主题交换的行为就像直接的一样。
2.代码示例
跟RabbitMQ(五)中的代码几乎一样
路由模式改为:topic
channel.exchangeDeclare(EXCHANGE_NAME, "topic");
发送者代码中
/**
* exchange 交换机
* routingKey 绑定键-->通配符形式
* props
* body 消息内容
*/
channel.basicPublish(EXCHANGE_NAME,"quick.orange.rabbit",null,msg.getBytes());
消费者1代码中
/**
* queue 队列名
* exchange 交换机
* routingKey 绑定键,绑定到交互及的时候会指定一个标记,只有和它一样的标记的消息才会被当前消费者接收到
* *(星号)可以代替一个单词。
* #(哈希)可以替代零个或多个单词。
*/
channel.queueBind(queueName,EXCHANGE_NAME,"*.orange.*");
消费者2代码中
/**
* queue 队列名
* exchange 交换机
* routingKey 绑定键,绑定到交互及的时候会指定一个标记,只有和它一样的标记的消息才会被当前消费者接收到
* *(星号)可以代替一个单词。
* #(哈希)可以替代零个或多个单词。
*/
channel.queueBind(queueName,EXCHANGE_NAME,"*.*.rabbit");
channel.queueBind(queueName,EXCHANGE_NAME," lazy.#");
路由键设置为“ quick.orange.rabbit ”的消息将传递到两个队列。消息“ lazy.orange.elephant ”也将发送给他们两个。另一方面,“ quick.orange.fox ”只会进入第一个队列,而“ lazy.brown.fox ”只会进入第二个队列。“ lazy.pink.rabbit ”将被传递到第二队只有一次,即使两个绑定匹配。“ quick.brown.fox ”与任何绑定都不匹配,因此将被丢弃。
如果我们违反合同并发送一个或四个单词的消息,例如“ 橙色 ”或“ quick.orange.male.rabbit ”,会发生什么?好吧,这些消息将不匹配任何绑定,并且将会丢失。
另一方面,“ lazy.orange.male.rabbit ”即使有四个单词,也将匹配最后一个绑定,并将其传送到第二个队列。