3.5.1 介绍
Topic类型的Exchange与Direct相比,都是可以根据RoutingKey把消息路由到不同的队列。
只不过Topic类型Exchange可以让队列在绑定BindingKey 的时候使用通配符!
BindingKey 一般都是有一个或多个单词组成,多个单词之间以.分割,例如: item.insert
通配符规则:
#:匹配零个或多个词*:匹配不多不少恰好1个词
举例:
item.#:能够匹配item.spu.insert或者item.spuitem.*:只能匹配item.spu
图示:
假如此时publisher发送的消息使用的RoutingKey共有四种:
china.news代表有中国的新闻消息;china.weather代表中国的天气消息;japan.news则代表日本新闻japan.weather代表日本的天气消息;
解释:
topic.queue1:绑定的是china.#,凡是以china.开头的routing key都会被匹配到,包括:
china.newschina.weather
topic.queue2:绑定的是#.news,凡是以.news结尾的routing key都会被匹配。包括:
china.newsjapan.news
3.5.2 测试
3.5.2.1 创建队列和交换机
接下来,我们就按照上图所示,来演示一下Topic交换机的用法。
首先,在控制台按照图示例子创建队列、交换机,并利用通配符绑定队列和交换机。
创建队列:topic.queue1、topic.queue2
创建交换机:hmall.topic
绑定队列:
topic.queue1:绑定的是china.#
topic.queue2:绑定的是#.news
最终结果如下:
3.5.2.2 消息接收
在consumer服务的SpringRabbitListener中添加方法:
@RabbitListener(queues = "topic.queue1") public void listenTopicQueue1(String msg){ System.out.println("消费者1接收到topic.queue1的消息:【" + msg + "】"); } @RabbitListener(queues = "topic.queue2") public void listenTopicQueue2(String msg){ System.out.println("消费者2接收到topic.queue2的消息:【" + msg + "】"); }
3.5.2.3 消息发送
在publisher服务的SpringAmqpTest类中添加测试方法:
/** * topicExchange */ @Test public void testSendTopicExchange() { // 交换机名称 String exchangeName = "hmall.topic"; // 消息 String message = "喜报!孙悟空大战哥斯拉,胜!"; // 发送消息 rabbitTemplate.convertAndSend(exchangeName, "china.news", message); }
执行测试方法,routingKey为china.news可以匹配topic.queue1和topic.queue2,日志输出:
消费者1接收到topic.queue1的消息:【喜报!孙悟空大战哥斯拉,胜!】 消费者2接收到topic.queue2的消息:【喜报!孙悟空大战哥斯拉,胜!】
更改routingKey为china.weather,只可以匹配到topic.queue1,日志输出:
消费者1接收到topic.queue1的消息:【喜报!孙悟空大战哥斯拉,胜!】
3.5.3 小结
描述下Direct交换机与Topic交换机的差异?
- Topic交换机接收的消息RoutingKey必须是多个单词,以
.分割 - Topic交换机与队列绑定时的bindingKey可以指定通配符
#:代表0个或多个词*:代表1个词