文章目录
0、简介
真正生产环境都会通过 exchange (交换机) 来发送消息,交换机的类型有以下三种:
- Fanout:广播;发送给绑定的每一个队列。
- Direct:定向;定向路由。
- Topic:话题;模糊路由。
1、Fanout 交换机
Fanout Exchange 会将接收到的消息广播到每一个跟其绑定的 Queue,所以也叫广播模式。
● 精简 Demo
- 在控制台创建队列 fanoutQueue1 和 fanoutQueue2
- 在控制台创建交换机 testFanout 并绑定上面两个队列
- 在 consumer 编写两个消费者方法,分别监听 fanoutQueue1 和 fanoutQueue2
- 在 publisher 中编写测试方法,向 testFanout 发送消息
◎ Publisher 代码
@Autowired
private RabbitTemplate rabbitTemplate;
public boolean doTestPublisher() {
String exchangeName = "testFanout";
String msg = "hello fanout!";
// 参数:交换机,routingKey, 消息
rabbitTemplate.convertAndSend(exchangeName, null, msg);
}
◎ Publisher 代码
@Component
public class MqTestConsumerListener {
@RabbitListener(queues = "fanoutQueue1")
public void fanoutQueue1Listener(String msg) {
System.out.println("\nfanoutQueue1接到了testFanout的消息:" + msg);
}
@RabbitListener(queues = "fanoutQueue2")
public void fanoutQueue2Listener(String msg) {
System.err.println("\nfanoutQueue2接到了testFanout的消息:" + msg);
}
}
◎ 结果
2、Direct 交换机
Direct Exchange 会将接收到的消息根据规则路由到指定的 Queue,因此被称为定向路由。
- 每一个 Queue 都与 Exchange 设置一个 BindingKey
- 发布者发送消息时,指定消息的 RoutingKey
- Exchange 将消息路由到 BindingKey 与消息 RoutingKey 一致的队列
如果 Exchange 绑定的多个队列设置了同一个 BindingKey,那么它便和 Fanout 交换机功能一样了。
● 精简 Demo
- 在控制台创建队列 directQueue1 和 directQueue2
- directQueue1 绑定 BindingKey 为 blue 和 red
- directQueue2 绑定 BindingKey 为 blue 和 yellow
- 在控制台创建交换机 testDirect 并绑定上面两个队列
- 在 consumer 编写两个消费者方法,分别监听 directQueue1 和 directQueue2
- 在 publisher 中编写测试方法,利用不同的 RoutingKey 向 testDirect 发送消息
◎ Publisher 代码
@Autowired
private RabbitTemplate rabbitTemplate;
public boolean doTestPublisher() {
String exchangeName = "testDirect";
// 参数:交换机,routingKey, 消息
rabbitTemplate.convertAndSend(exchangeName, "blue", "hello blue direct!");
rabbitTemplate.convertAndSend(exchangeName, "red", "hello red direct!");
rabbitTemplate.convertAndSend(exchangeName, "yellow", "hello yellow direct!");
}
◎ Publisher 代码
@Component
public class MqTestConsumerListener {
@RabbitListener(queues = "directQueue1")
public void directQueue1Listener(String msg) {
System.out.println("\ndirectQueue1接到了testDirect的消息:" + msg);
}
@RabbitListener(queues = "directQueue2")
public void directQueue2Listener(String msg) {
System.err.println("\ndirectQueue2接到了testDirect的消息:" + msg);
}
}
◎ 结果
3、Topic 交换机
Topic Exchange 与 Direct Exchange 类似,区别在于 routingKey 可以是多个单词的列表,并且以 .
分割。
- Queue 与 Exchange 指定 BindingKey 时可以使用通配符:
- #:代指 ≥ 0 个单词
- *:代指 1 个单词
● 精简 Demo
- 在控制台创建队列 topicQueue1 和 topicQueue2
- topicQueue1 绑定 BindingKey 为 china.#
- topicQueue2 绑定 BindingKey 为 #.news
- 在控制台创建交换机 testTopic 并绑定上面两个队列
- 在 consumer 编写两个消费者方法,分别监听 topicQueue1 和 topicQueue2
- 在 publisher 中编写测试方法,利用不同的 RoutingKey 向 testTopic 发送消息
◎ Publisher 代码
@Autowired
private RabbitTemplate rabbitTemplate;
public boolean doTestPublisher() {
String exchangeName = "testTopic";
// 参数:交换机,routingKey, 消息
rabbitTemplate.convertAndSend(exchangeName, "china.news", "hello China News topic!");
rabbitTemplate.convertAndSend(exchangeName, "china.sports", "hello China Sports topic!");
rabbitTemplate.convertAndSend(exchangeName, "Canada.news", "hello Canada News topic!");
}
◎ Publisher 代码
@Component
public class MqTestConsumerListener {
@RabbitListener(queues = "topicQueue1")
public void topicQueue1Listener(String msg) {
System.out.println("\ntopicQueue1接到了testTopic的消息:" + msg);
}
@RabbitListener(queues = "topicQueue2")
public void topicQueue2Listener(String msg) {
System.err.println("\ntopicQueue2接到了testTopic的消息:" + msg);
}
}