小编今天主要讲的是RabbitMQ中的Topic模式
Topic类型的Exchange与Direct相比,都是可以根据RoutingKey把消息路由到不同的队列。只不过Topic类型Exchange可以让队列在绑定Routing key 的时候使用通配符!
Routingkey 一般都是有一个或多个单词组成,多个单词之间以”.”分割,例如: item.insert
通配符规则:
#:匹配一个或多个词
*:匹配不多不少恰好1个词
关于通配符的使用?
item.#:能够匹配item.spu.insert 或者 item.spu
item.*:只能匹配item.spu
解释:
- Queue1:绑定的是china.# ,因此凡是以 china.开头的routing key 都会被匹配到。包括china.news和china.weather
- Queue2:绑定的是#.news ,因此凡是以 .news结尾的 routing key 都会被匹配。包括china.news和japan.news
示例代码?
1.消息发送
在publisher服务的SpringAmqpTest类中添加测试方法:
/**
* topicExchange
*/
@Test
public void testSendTopicExchange() {
// 交换机名称
String exchangeName = "itcast.topic";
// 消息
String message = "喜报!孙悟空大战哥斯拉,胜!";
// 发送消息
rabbitTemplate.convertAndSend(exchangeName, "china.news", message);
}
2.消息接收
@RabbitListener(bindings = @QueueBinding(
value = @Queue(name = "topic.queue1"),
exchange = @Exchange(name = "itcast.topic", type = ExchangeTypes.TOPIC),
key = "china.#"
))
public void listenTopicQueue1(String msg){
System.out.println("消费者接收到topic.queue1的消息:【" + msg + "】");
}
@RabbitListener(bindings = @QueueBinding(
value = @Queue(name = "topic.queue2"),
exchange = @Exchange(name = "itcast.topic", type = ExchangeTypes.TOPIC),
key = "#.news"
))
public void listenTopicQueue2(String msg){
System.out.println("消费者接收到topic.queue2的消息:【" + msg + "】");
}
如何动态获取所有队列?
其实RabbitMQ中一次性获取交换机下所有队列的信息的方法,最常用的无非就是Fanout模式 中文的理解意思又叫广播,我们可以声明式一个Fanout的交换机,然后另起一条队列fanoutQueue;将两者进行绑定,这样子fanoutQueue队列也能获取到Fanout交换机下发送给所有队列的每一个消息。
如果是项目中已经存在交换机了并且是Topic模式;然后交换机与队列之间绑定的routingKey没有使用通配符的形式。
关键点注意啦!!!
这种情况我们就可以合理使用通配符来解决我们动态获取所有队列的消息,#** 和 * ;当一个队列绑定键是#,那么这个队列将接收所有数据,就有点像 fanout 了,所以我们只需要另起一个队列绑定指定的交换机后将Routing Key 设置为 “#”就ok了。**
首先去生产者模块写一个测试类:
@Test
public void testFanoutExchange() {
// 交换机名称
String exchangeName = "robot.change";
// 消息
String message = "bug消失-bug消失-bug消失-bug消失-bug消失-bug消失";
String message1 = "安静的做一个美男子就好了";
String message2 = "未来几年希望程序员鼓励师这个岗位能够普遍实现";
rabbitTemplate.convertAndSend(exchangeName, "autodoor", message);
rabbitTemplate.convertAndSend(exchangeName, "lift", message1);
rabbitTemplate.convertAndSend(exchangeName, "supply", message2);
}
然后在我们的消费者端创建一个配置类,小编这里使用的是RabbitmMQ注解的方式声明交换机与队列的消息
@Configuration
@Slf4j
public class TopicConfig {
@RabbitListener(bindings = @QueueBinding(value = @Queue(name = "api.queue"),
exchange = @Exchange(name = "robot.change", type = ExchangeTypes.TOPIC),
key = "#"))
public void listenAPiQueue(String msgAll){
System.out.println("获取到的所有队列消息如下: " + msgAll);
}
}
最后的结果就是这个 api.queue 队列获取到了交换机发给他底下所有队列的一个消息。
**希望上面的信息能够帮助到我们的每一个位小伙伴!!!
**
: