全部学科
NodeJS全栈
nodejs
Python全栈
python
小程序首页
📅 2026-05-22 8 分钟 ✍️ juanwangdev

Fanout 交换机

Fanout交换机将消息广播到所有绑定队列,忽略路由键实现发布订阅模式。

定义

Fanout交换机接收消息后,无条件将消息副本投递到所有与其绑定的队列,路由键被完全忽略。这是最快的交换机类型,适用于一对多消息分发场景。

核心机制

广播流程

  1. 生产者发送消息到Fanout交换机(路由键可为空)
  2. 交换机接收消息后,获取所有绑定队列列表
  3. 为每个绑定队列创建消息副本并投递
  4. 各队列独立消费消息,互不影响

声明与绑定

Java
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;

public class FanoutExchangeExample {
    private static final String EXCHANGE_NAME = "broadcast_logs";

    public static void main(String[] args) throws Exception {
        ConnectionFactory factory = new ConnectionFactory();
        factory.setHost("localhost");
        
        try (Connection connection = factory.newConnection();
             Channel channel = connection.createChannel()) {
            
            // 声明Fanout交换机
            channel.exchangeDeclare(EXCHANGE_NAME, "fanout", true);
            
            // 声明三个队列
            channel.queueDeclare("queue_email", true, false, false, null);
            channel.queueDeclare("queue_sms", true, false, false, null);
            channel.queueDeclare("queue_webhook", true, false, false, null);
            
            // 绑定所有队列到Fanout交换机(路由键被忽略)
            channel.queueBind("queue_email", EXCHANGE_NAME, "");
            channel.queueBind("queue_sms", EXCHANGE_NAME, "");
            channel.queueBind("queue_webhook", EXCHANGE_NAME, "");
            
            // 发布消息(路由键任意,通常传空字符串)
            String message = "Order created: #12345";
            channel.basicPublish(EXCHANGE_NAME, "", null, 
                    message.getBytes("UTF-8"));
            
            System.out.println("Broadcast message sent: " + message);
        }
    }
}

临时队列广播

适用于日志收集、事件通知等只需运行时接收消息的场景:

Java
import com.rabbitmq.client.*;
import java.io.IOException;

public class FanoutTemporaryConsumer {
    private static final String EXCHANGE_NAME = "broadcast_logs";

    public static void main(String[] args) throws Exception {
        ConnectionFactory factory = new ConnectionFactory();
        factory.setHost("localhost");
        
        Connection connection = factory.newConnection();
        Channel channel = connection.createChannel();
        
        channel.exchangeDeclare(EXCHANGE_NAME, "fanout", true);
        
        // 声明临时队列(非持久化、独占、自动删除)
        String queueName = channel.queueDeclare().getQueue();
        
        // 绑定到Fanout交换机
        channel.queueBind(queueName, EXCHANGE_NAME, "");
        
        System.out.println("Listening for broadcast messages...");
        
        DeliverCallback deliverCallback = (consumerTag, delivery) -> {
            String message = new String(delivery.getBody(), "UTF-8");
            System.out.println("Received: " + message);
            channel.basicAck(delivery.getEnvelope().getDeliveryTag(), false);
        };
        
        channel.basicConsume(queueName, false, deliverCallback, consumerTag -> {});
    }
}

注意事项

  • Fanout交换机忽略所有路由键,消息必然投递到所有绑定队列
  • 性能最高(无需路由计算),适用于广播、通知、事件分发
  • 无法实现选择性投递,若需过滤应改用Direct或Topic交换机
  • 临时队列断开连接后自动删除,适合日志收集等短暂订阅场景
  • 绑定多个队列时,交换机为每个队列创建独立消息副本,内存占用与队列数成正比

要点总结

  • Fanout交换机将消息广播到所有绑定队列,路由键无效
  • 适用于发布订阅、事件通知、日志收集等一对多场景
  • 性能最优,无需路由匹配计算
  • 支持临时队列实现运行时动态订阅
  • 无法选择性过滤消息,需过滤时应使用其他交换机类型

文章存放路径:D:\git2\jwdev\articles\RABBITMQ\进阶\交换机类型详解\Fanout 交换机.md

📝 发现内容有误?点击此处直接编辑

← 上一篇 Direct 交换机
下一篇 → Topic 交换机
想查看更多题目和详细解析?
小程序提供完整的题库、模拟考试和详细解析
马上就来

长按或扫描二维码,立即体验

扫码体验小程序
马上就来
使用微信扫描二维码
立即体验完整题库