RabbitMQ三种交换机的基本使用方法

RabbitMQ 中的交换机(Exchange)是消息路由的核心组件,它负责将生产者发送的消息根据一定的路由规则分发到队列。RabbitMQ 提供了三种常见的交换机类型:**Direct Exchange**、**Fanout Exchange** 和 **Topic Exchange**。每种交换机类型都有不同的路由方式,适用于不同的场景。

1. **Direct Exchange** (直接交换机)

1.1 介绍

  • **Direct Exchange** 是最常见的交换机类型,它根据消息的 **Routing Key**(路由键)将消息路由到一个或多个匹配的队列。

  • 如果队列绑定时指定了特定的路由键,那么只有生产者发送的消息的路由键与该队列绑定的路由键完全匹配时,消息才会被路由到该队列。

1.2 用法

  • **适用场景**:适用于发送特定消息到特定队列的场景。

  • **消息路由**:通过 `Routing Key` 来精确匹配队列。

1.3 配置和使用

```java

@Bean

public DirectExchange directExchange() {

return new DirectExchange("directExchange", true, false); // durable,是否持久化

}

@Bean

public Binding transferFileBinding(Queue transferFileQueue, DirectExchange directExchange) {

return BindingBuilder.bind(transferFileQueue)

.to(directExchange)

.with("transferFileRoutingKey");

}

```

  • **消息发送**:指定交换机名称、路由键发送消息。

```java

amqpTemplate.convertAndSend("directExchange", "transferFileRoutingKey", message);

```

1.4 消息路由示例

假设有两个队列绑定到 `directExchange`:

  • 队列 `queue1` 绑定路由键为 `key1`

  • 队列 `queue2` 绑定路由键为 `key2`

如果生产者发送消息时设置路由键为 `key1`,那么只有 `queue1` 会接收到该消息;如果路由键为 `key2`,则 `queue2` 会接收到。


2. **Fanout Exchange** (扇出交换机)

2.1 介绍

  • **Fanout Exchange** 将接收到的消息广播到所有绑定到该交换机的队列,而不关心消息的路由键。

  • 它不会使用路由键,而是将消息发给所有的消费者队列。

2.2 用法

  • **适用场景**:适用于广播消息的场景,例如推送消息、实时通知等。

  • **消息路由**:与路由键无关,消息会被广播到所有绑定的队列。

2.3 配置和使用

```java

@Bean

public FanoutExchange fanoutExchange() {

return new FanoutExchange("fanoutExchange", true, false); // durable,是否持久化

}

@Bean

public Binding binding1(Queue queue1, FanoutExchange fanoutExchange) {

return BindingBuilder.bind(queue1).to(fanoutExchange);

}

```

  • **消息发送**:发送到交换机,不需要指定路由键。

```java

amqpTemplate.convertAndSend("fanoutExchange", "", message); // 路由键为空

```

2.4 消息路由示例

假设有两个队列绑定到 `fanoutExchange`,无论消息的内容是什么,消息都会同时发送到这两个队列。

  • 队列 `queue1` 和 `queue2` 都绑定到 `fanoutExchange`,生产者发送一条消息时,这条消息会同时发送到 `queue1` 和 `queue2`。

3. **Topic Exchange** (主题交换机)

3.1 介绍

  • **Topic Exchange** 允许根据 **Routing Key** 中的部分匹配规则来路由消息。

  • 它支持更灵活的消息路由,可以使用通配符(`*` 和 `#`)来匹配多个路由键。

  • `*`:匹配一个词

  • `#`:匹配零个或多个词

3.2 用法

  • **适用场景**:适用于需要复杂路由逻辑的场景,比如根据多个维度(如日志级别、类别等)进行消息路由。

  • **消息路由**:通过路由键的模式匹配来决定消息发送到哪些队列。

3.3 配置和使用

```java

@Bean

public TopicExchange topicExchange() {

return new TopicExchange("topicExchange", true, false); // durable,是否持久化

}

@Bean

public Binding binding1(Queue queue1, TopicExchange topicExchange) {

return BindingBuilder.bind(queue1)

.to(topicExchange)

.with("*.log.*"); // 匹配类似 "error.log.java" 这样的路由键

}

```

  • **消息发送**:发送消息时指定路由键,支持多层级的通配符。

```java

amqpTemplate.convertAndSend("topicExchange", "error.log.java", message);

```

3.4 消息路由示例

假设有以下两个队列绑定到 `topicExchange`:

  • 队列 `queue1` 绑定的路由键模式是 `*.log.*`,表示它会接收以 `.log.` 为中间部分的路由键(如 `error.log.java`、`info.log.js`)。

  • 队列 `queue2` 绑定的路由键模式是 `*.error`,表示它会接收以 `.error` 结尾的路由键(如 `critical.error`)。

如果生产者发送消息,路由键为 `error.log.java`,那么:

  • `queue1` 会接收到消息(因为路由键匹配 `*.log.*`)。

  • `queue2` 不会接收到该消息(因为路由键不匹配 `*.error`)。


比较和选择

| 交换机类型 | 路由规则 | 适用场景 |

|-------------------|----------|-----------------------------------------------|

| **Direct Exchange** | 精确匹配 `Routing Key` | 消息发送到特定队列,如任务分发等 |

| **Fanout Exchange** | 广播到所有队列 | 广播通知、实时推送等 |

| **Topic Exchange** | 基于模式匹配的 `Routing Key` | 复杂的路由需求,如按日志级别、类别分发等 |

结论

  • **Direct Exchange**:适用于一对一的精确消息路由。

  • **Fanout Exchange**:适用于消息广播到所有订阅的队列。

  • **Topic Exchange**:适用于灵活、复杂的消息路由,支持路由键的通配符匹配。

根据实际业务需求,选择合适的交换机类型,可以帮助更高效地实现消息传递和路由策略。

相关推荐
黄雪超17 分钟前
JVM——打开JVM后门的钥匙:反射机制
java·开发语言·jvm
有梦想的攻城狮25 分钟前
spring中的@RabbitListener注解详解
java·后端·spring·rabbitlistener
李斯维28 分钟前
循序渐进 Android Binder(二):传递自定义对象和 AIDL 回调
android·java·android studio
androidwork29 分钟前
OkHttp 3.0源码解析:从设计理念到核心实现
android·java·okhttp·kotlin
Java水解30 分钟前
MySQL DQL全面解析:从入门到精通
后端·mysql
Aurora_NeAr30 分钟前
Apache Spark详解
大数据·后端·spark
程序员岳焱31 分钟前
Java 程序员成长记(二):菜鸟入职之 MyBatis XML「陷阱」
java·后端·程序员
hello早上好31 分钟前
BeanFactory 实现
后端·spring·架构
我命由我1234532 分钟前
Spring Boot 项目集成 Redis 问题:RedisTemplate 多余空格问题
java·开发语言·spring boot·redis·后端·java-ee·intellij-idea
面朝大海,春不暖,花不开33 分钟前
Spring Boot消息系统开发指南
java·spring boot·后端