深入理解 RabbitMQ 的交换机类型(Exchange Types)

深入理解 RabbitMQ 的交换机类型(Exchange Types)

一、什么是交换机(Exchange)?

RabbitMQ 的核心工作机制可以总结为:

生产者 ➝ 交换机 ➝ 队列 ➝ 消费者
在这里插入图片描述

交换机负责接收消息,并根据不同类型的路由规则,将消息转发到一个或多个队列

每个交换机都有:

  • 名称(可以为空)
  • 类型(direct、fanout、topic、headers)
  • 绑定关系(Binding)用于指定哪些队列接收哪些消息

二、交换机的四种类型

类型名称特点说明
直连型direct精准路由,依据 routingKey 完全匹配
扇出型fanout广播模式,忽略 routingKey,发送给所有队列
主题型topic模糊匹配,支持通配符(* 和 #)
头部型headers根据消息头(headers)匹配路由规则

三、direct(直连)交换机

特点

  • routingKey 精准匹配
  • 每条消息只会进入绑定了指定 routingKey 的队列

在这里插入图片描述
🧪 示例
在这里插入图片描述

  1. 声明一个名为hmall.direct的交换机
  2. 声明队列direct.queue1,绑定hmall.directbindingKeybludred
  3. 声明队列direct.queue2,绑定hmall.directbindingKeyyellowred
  4. consumer服务中,编写两个消费者方法,分别监听direct.queue1direct.queue2
  5. publisher中编写测试方法,向hmall.direct发送消息

消息接收:

@RabbitListener(queues = "direct.queue1")
public void listenDirectQueue1(String msg) {
    System.out.println("消费者1接收到direct.queue1的消息:【" + msg + "】");
}

@RabbitListener(queues = "direct.queue2")
public void listenDirectQueue2(String msg) {
    System.out.println("消费者2接收到direct.queue2的消息:【" + msg + "】");
}

消息发送

@Test
public void testSendDirectExchange() {
    // 交换机名称
    String exchangeName = "hmall.direct";
    // 消息
    String message = "红色警报!日本乱排核废水,导致海洋生物变异,惊现哥斯拉!";
    // 发送消息
    rabbitTemplate.convertAndSend(exchangeName, "bule", message);
}

消息将被投递到绑定了 "blue" 的队列。

四、fanout(扇出)交换机

✨ 特点

  • 不关心 routingKey
  • 消息被 广播到所有绑定的队列
    在这里插入图片描述
  • 1) 可以有多个队列
  • 2) 每个队列都要绑定到Exchange(交换机)
  • 3) 生产者发送的消息,只能发送到交换机
  • 4) 交换机把消息发送给绑定过的所有队列
  • 5) 订阅队列的消费者都能拿到消息

🧪 示例
在这里插入图片描述

  • 创建一个名为 hmall.fanout的交换机,类型是Fanout
  • 创建两个队列fanout.queue1fanout.queue2,绑定到交换机hmall.fanout

消息发送:

@Test
public void testFanoutExchange() {
    // 交换机名称
    String exchangeName = "hmall.fanout";
    // 消息
    String message = "hello, everyone!";
    rabbitTemplate.convertAndSend(exchangeName, "", message);
}

消息接收:

@RabbitListener(queues = "fanout.queue1")
public void listenFanoutQueue1(String msg) {
    System.out.println("消费者1接收到Fanout消息:【" + msg + "】");
}

@RabbitListener(queues = "fanout.queue2")
public void listenFanoutQueue2(String msg) {
    System.out.println("消费者2接收到Fanout消息:【" + msg + "】");
}

消息会同时发送给fanout.queue1fanout.queue2

✅ 应用场景

  • 广播通知(如:发短信、发邮件)
  • 多系统日志收集

五、topic(主题)交换机

✨ 特点

  • 支持模糊匹配 routingKey(以点分隔)
  • 通配符说明:
    • * 匹配一个单词(例如 order.*
    • # 匹配多个单词(例如 order.#

🧪 示例
在这里插入图片描述
假如此时publisher发送的消息使用的RoutingKey共有四种:

  • china.news 代表有中国的新闻消息;
  • china.weather 代表中国的天气消息;
  • japan.news 则代表日本新闻
  • japan.weather 代表日本的天气消息;

解释:

  • topic.queue1:绑定的是china.# ,凡是以 china.开头的routing key 都会被匹配到,包括:
    • china.news
    • china.weather
  • topic.queue2:绑定的是#.news ,凡是以 .news结尾的 routing key 都会被匹配。包括:
    • china.news
    • japan.news

消息发送:

/**
 * topicExchange
 */
@Test
public void testSendTopicExchange() {
    // 交换机名称
    String exchangeName = "hmall.topic";
    // 消息
    String message = "喜报!孙悟空大战哥斯拉,胜!";
    // 发送消息
    rabbitTemplate.convertAndSend(exchangeName, "china.news", message);
}

消息接收:

@RabbitListener(queues = "topic.queue1")
public void listenTopicQueue1(String msg){
    System.out.println("消费者1接收到topic.queue1的消息:【" + msg + "】");
}

@RabbitListener(queues = "topic.queue2")
public void listenTopicQueue2(String msg){
    System.out.println("消费者2接收到topic.queue2的消息:【" + msg + "】");
}

✅ 应用场景

  • 复杂消息分类系统
  • 动态可扩展的路由规则(如日志系统)

六、headers(头部)交换机

✨ 特点

  • routingKey 不再使用
  • 根据消息头属性进行路由(headers 字段)
  • 支持 x-match=allx-match=any(全部匹配 / 任意匹配)

🧪 示例

Map<String, Object> headers = new HashMap<>();
headers.put("format", "pdf");
headers.put("type", "report");
AMQP.BasicProperties props = new AMQP.BasicProperties.Builder()
    .headers(headers)
    .build();

channel.basicPublish("headersExchange", "", props, body);

队列绑定时设置:

Map<String, Object> args = new HashMap<>();
args.put("x-match", "all");
args.put("format", "pdf");
args.put("type", "report");
channel.queueBind("reportQueue", "headersExchange", "", args);

✅ 应用场景

  • 消息内容非常复杂,不适合用 routingKey
  • 使用 HTTP-style 路由方式

七、总结对比

类型是否用 routingKey是否支持通配符路由依据推荐场景
direct✅ 是❌ 否routingKey 精准匹配单类型消息精准投递
fanout❌ 否❌ 否广播所有队列广播推送、群发消息
topic✅ 是✅ 是通配符匹配多类型消息、日志系统
headers❌ 否❌ 否headers匹配复杂条件路由、企业集成系统
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值