RabbitMQ交换器的三种模式
前言:本文是总结整理出来的,若有错误的地方请指出,记得每天微笑。
直连模式(direct)
-
什么是直连模式
任何发送到Direct Exchange的消息都会被转发到RouteKey中指定的Queue。- 需要一个 “RouteKey” 就是要发送队列的名字
- 不需要绑定任何一个queue
- 使用的是rabbitMQ自带的Exchange
- 如果vhost中不存在RouteKey中指定的队列名,则该消息会被抛弃。
-
使用场景
我们需要将消息发给唯一一个节点时使用这种模式。 -
创建队列
Durability: 是否做持久化
Auto delete: 是否自动删除 -
direct
- 创建springboot项目进行测试
<!--所需要的包-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
- 配置文件
spring:
rabbitmq:
host: localhost
- 编写listener 消费者
@Component
@RabbitListener(queues = "directqueue") //填写刚刚设置的队列
public class DirectListener {
@RabbitHandler
public void showMsg(String msg) {
System.out.println(msg);
}
}
- 编写生产者测试
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest
public class MqApplicationTests {
@Autowired
private RabbitTemplate rabbitTemplate;
@Test
public void contextLoads() {
rabbitTemplate.convertAndSend("directqueue", "我是direct模式");
}
}
控制台输出
分列模式(Fanout)
- 什么是分列模式
任何发送到Direct Exchange的消息都会被转发到RouteKey中指定的Queue。
- 不需要 “RouteKey”
- 这个模式需要将Exchange与Queue进行绑定,一个Exchange可以与多个queue绑定
- 如果交换器没有与任何一个queue绑定,消息就会背抛弃
- 使用场景
当我们需要将消息一次发给多个队列时,需要使用这种模式。 - Fanout
- 新建交换器
- 创建2个队列(用于绑定交换器)
- 将fanouta和fanoutb绑定到交换器(fanoutexchange)
- 绑定成功
- 编写生产者
监听fanouta消息
@RabbitListener(queues = "fanouta") //监听fanouta
@Component
public class FanoutAListener {
@RabbitHandler
public void getMsg(String msg) {
System.out.println("fanouta接收到的:"+msg);
}
}
监听fanoutb消息
@RabbitListener(queues = "fanoutb") // 监听fanoutb
@Component
public class FanoutBListener {
@RabbitHandler
public void getMsg(String msg) {
System.out.println(" fanouta接收到的:"+msg);
}
}
- 编写消费者
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest
public class MqApplicationTests {
@Autowired
private RabbitTemplate rabbitTemplate;
@Test
public void fanout() {
rabbitTemplate.convertAndSend("fanoutexchange", "","我是fanout模式");
}
}
- 输出
发送到交换器,交换器会发送到fanouta与fanoutb队列中
主题模式(Topic)
- 什么是主题模式
任何发送到Topic Exchange的消息都会被转发到所有关心RouteKey中指定话题的Queue 上
- 这种模式较为复杂,简单来说,就是每个队列都有其关心的主题,所有的消息都带有一个“标题”(RouteKey),Exchange会将消息转发到所有关注主题能与RouteKey模糊匹配的队列。
- 这种模式需要RouteKey,也许要提前绑定Exchange与Queue。
- 在进行绑定时,要提供一个该队列关心的主题,如“#.log.#”表示该队列关心所有涉及 log的消息(一个RouteKey为”MQ.log.error”的消息会被转发到该队列)。
- “#”表示0个或若干个关键字,“”表示一个关键字。如“log.”能与“log.warn”匹配,无法与“log.warn.timeout”匹配;但是“log.#”能与上述两者匹配。
- 同样,如果Exchange没有发现能够与RouteKey匹配的Queue,则会抛弃此消息
- Topic
- 新建交换器
- 创建队列
- 与交换器绑定
- 编写生产者
监听topica
@RabbitListener(queues = "topica")
@Component
public class Topica {
@RabbitHandler
public void showMsg(String msg) {
System.out.println("topica接收到的:"+msg);
}
}
监听topicb
@RabbitListener(queues = "topicb")
@Component
public class Topicb {
@RabbitHandler
public void showMsg(String msg) {
System.out.println("topicb接收到的:"+msg);
}
}
监听topicc
@RabbitListener(queues = "topicc")
@Component
public class Topicc {
@RabbitHandler
public void showMsg(String msg) {
System.out.println("topicc接收到的:"+msg);
}
}
- 编写消费者
- 测试#.change
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest
public class MqApplicationTests {
@Autowired
private RabbitTemplate rabbitTemplate;
@Test
public void topica() {
rabbitTemplate.convertAndSend("topicexchange", "a.change","我是topic模式");
}
}
- 输出结果
- 测试ex.#
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest
public class MqApplicationTests {
@Autowired
private RabbitTemplate rabbitTemplate;
@Test
public void topicb() {
rabbitTemplate.convertAndSend("topicexchange", "ex.a","我是topic模式");
}
}
- 输出结构
- 我们测试下ex.change
@Test
public void topicc () {
rabbitTemplate.convertAndSend("topicexchange", "ex.change","我是topic模式");
}
- 输出结果
# 匹配多个或一个
* 匹配一个(用的较少)