RabbitMQ 中的交换机学习

RabbitMQ 中的交换机学习


一、直接交换机(Direct Exchange)

1. 介绍

Direct 交换机将消息路由到绑定了指定 Routing Key 的队列中。每条消息都有一个 Routing Key,当队列绑定到 Direct 交换机时,它需要一个指定的 Routing Key。只有消息的 Routing Key 与队列绑定的 Routing Key 完全匹配时,消息才会路由到该队列中。

2. 代码示例
- 发送消息
java 复制代码
public class DirectLogs {
    public static final String exchange_name = "direct_logs";
    public static void main(String[] args) throws Exception {
        Channel channel = RabbitMqUtils.getChannel();
        Scanner sc = new Scanner(System.in);
        while(sc.hasNext()){
            String message = sc.next();
            channel.basicPublish(exchange_name, "error", null, message.getBytes("UTF-8"));
            System.out.println("生产者发送消息:" + message);
        }
    }
}
- 接收消息
java 复制代码
public class ReceiveLogsTopic01 {
    public static final String EXCHANGE_NAME = "direct_logs";
    public static final String QUEUE_NAME = "console";
    public static void main(String[] args) throws Exception {
        Channel channel = RabbitMqUtils.getChannel();
        channel.exchangeDeclare(EXCHANGE_NAME, BuiltinExchangeType.DIRECT);
        channel.queueDeclare(QUEUE_NAME, false, false, false, null);
        channel.queueBind(QUEUE_NAME, EXCHANGE_NAME, "info");
        channel.queueBind(QUEUE_NAME, EXCHANGE_NAME, "warning");

        DeliverCallback deliverCallback = (consumerTag, message) -> {
            System.out.println("ReceiveLogsTopic01接收到的消息:" + new String(message.getBody(), "UTF-8"));
        };
        channel.basicConsume(QUEUE_NAME, true, deliverCallback, consumerTag -> {});
    }
}
- 结果

消息通过 Direct 交换机路由到对应队列:


二、主题交换机(Topic Exchange)

1. 介绍

Topic 交换机是基于通配符进行路由的交换机。它允许队列绑定的 Routing Key 使用 *(匹配一个词)和 #(匹配零个或多个词)作为通配符。它适用于需要模糊匹配的场景,例如日志系统。

2. 代码示例
- 发送消息
java 复制代码
public class EmitLog {
    public static final String exchange_name = "topic_logs";
    public static void main(String[] args) throws Exception {
        Channel channel = RabbitMqUtils.getChannel();
        Map<String, String> bindingKeyMap = new HashMap<>();
        bindingKeyMap.put("quick.orange.rabbit", "被队列 Q1Q2 接收到");
        bindingKeyMap.put("lazy.orange.elephant", "被队列 Q1Q2 接收到");
        bindingKeyMap.put("quick.orange.fox", "被队列 Q1 接收到");
        bindingKeyMap.put("lazy.brown.fox", "被队列 Q2 接收到");
        bindingKeyMap.put("lazy.pink.rabbit", "虽然满足两个绑定但只被队列 Q2 接收一次");

        for (Map.Entry<String, String> entry : bindingKeyMap.entrySet()) {
            String key = entry.getKey();
            String message = entry.getValue();
            channel.basicPublish(exchange_name, key, null, message.getBytes("UTF-8"));
            System.out.println("生产者发出消息:" + message);
        }
    }
}
- 接收消息
java 复制代码
public class ReceiveLogsTopic01 {
    public static final String exchange_name = "topic_logs";
    public static void main(String[] args) throws Exception {
        Channel channel = RabbitMqUtils.getChannel();
        channel.exchangeDeclare(exchange_name, "topic");
        String queue_name = "Q1";
        channel.queueDeclare(queue_name, false, false, false, null);
        channel.queueBind(queue_name, exchange_name, "*.orange.*");

        DeliverCallback deliverCallback = (consumerTag, message) -> {
            System.out.println("接收到的消息:" + new String(message.getBody(), "UTF-8"));
            System.out.println("接收队列:" + queue_name + "  绑定键:" + message.getEnvelope().getRoutingKey());
        };
        channel.basicConsume(queue_name, true, deliverCallback, consumerTag -> {});
    }
}

三、扇出交换机(Fanout Exchange)

1. 介绍

Fanout 交换机是最简单的交换机类型,它会将消息广播给所有与之绑定的队列,而不考虑消息的 Routing Key。通常用于广播消息,比如多服务实例之间的消息同步。

2. 代码示例
- 发送消息
java 复制代码
public class EmitLog {
    public static final String exchange_name = "logs";
    public static void main(String[] args) throws Exception {
        Channel channel = RabbitMqUtils.getChannel();
        channel.exchangeDeclare(exchange_name, "fanout");
        Scanner sc = new Scanner(System.in);
        while(sc.hasNext()){
            String message = sc.next();
            channel.basicPublish(exchange_name, "", null, message.getBytes());
            System.out.println("生产者发送消息:" + message);
        }
    }
}
- 接收消息
java 复制代码
public class ReceiveLog01 {
    public static final String exchange_name = "logs";
    public static void main(String[] args) throws Exception {
        Channel channel = RabbitMqUtils.getChannel();
        channel.exchangeDeclare(exchange_name, "fanout");
        String queueName = channel.queueDeclare().getQueue();
        channel.queueBind(queueName, exchange_name, "");

        DeliverCallback deliverCallback = (consumerTag, message) -> {
            System.out.println("接收到的消息:" + new String(message.getBody(), "UTF-8"));
        };
        channel.basicConsume(queueName, true, deliverCallback, consumerTag -> {});
    }
}

小结

  • Direct Exchange:消息通过精确匹配的 Routing Key 路由到绑定的队列。
  • Topic Exchange:消息通过通配符匹配的 Routing Key 路由到队列,适用于模糊匹配场景。
  • Fanout Exchange:消息会被广播给所有与之绑定的队列,不考虑 Routing Key,适用于广播场景。
相关推荐
萌新小码农‍7 小时前
Spring框架学习day7--SpringWeb学习(概念与搭建配置)
学习·spring·状态模式
蓝婷儿7 小时前
6个月Python学习计划 Day 15 - 函数式编程、高阶函数、生成器/迭代器
开发语言·python·学习
行云流水剑7 小时前
【学习记录】深入解析 AI 交互中的五大核心概念:Prompt、Agent、MCP、Function Calling 与 Tools
人工智能·学习·交互
一弓虽7 小时前
zookeeper 学习
分布式·学习·zookeeper
苗老大7 小时前
MMRL: Multi-Modal Representation Learning for Vision-Language Models(多模态表示学习)
人工智能·学习·语言模型
xhyu618 小时前
【学习笔记】On the Biology of a Large Language Model
笔记·学习·语言模型
小白杨树树8 小时前
【SSM】SpringMVC学习笔记7:前后端数据传输协议和异常处理
笔记·学习
dddaidai12312 小时前
kafka入门学习
分布式·学习·kafka
明月清了个风12 小时前
数据结构与算法学习笔记(Acwing 提高课)----动态规划·树形DP
笔记·学习·动态规划·树形dp