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**:适用于灵活、复杂的消息路由,支持路由键的通配符匹配。

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

相关推荐
Rust研习社6 分钟前
组合真的优于继承吗?为什么 Rust 和 Go 都拥抱组合舍弃继承?
后端·rust·编程语言
IT_陈寒30 分钟前
JavaScript的闭包把我坑惨了,说好的内存会自动回收呢?
前端·人工智能·后端
CaffeinePro1 小时前
Pydantic深度使用:数据校验、枚举、ORM映射
后端·fastapi
Chenyiax2 小时前
从 Chat 到 Responses:OpenAI API 抽象为什么变了?
后端
MariaH2 小时前
Koa和Express的区别
后端
MariaH2 小时前
Koa框架的使用
后端
luckdewei3 小时前
那个用 passlib 做认证的新同事,上线第一天就把用户密码写进了日志
后端
ping某4 小时前
为什么 Nginx 明明监听了 80,转发后端时却用了 4xxxx 端口?
后端·nginx
JustHappy4 小时前
我汇总了身边朋友的经历才发现,其实第一份实习是最难找的......
前端·后端·面试
uhakadotcom4 小时前
在python 的 工程化架构中 ,什么是 薄包装器层?
后端·面试·github