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,适用于广播场景。
相关推荐
现代科技改变命运2 小时前
泛型的学习
学习
Adorable老犀牛2 小时前
阿里云-基于通义灵码实现高效 AI 编码 | 8 | 上手实操:LeetCode学习宝典,通义灵码赋能算法高效突破
学习·算法·leetcode
LFly_ice3 小时前
学习React-10-useTransition
前端·学习·react.js
知识分享小能手3 小时前
React学习教程,从入门到精通,React 构造函数(Constructor)完整语法知识点与案例详解(16)
前端·javascript·学习·react.js·架构·前端框架·vue
淮北也生橘124 小时前
Linux的V4L2视频框架学习笔记
linux·笔记·学习·音视频·嵌入式linux
mysla5 小时前
嵌入式学习day46-硬件—汇编
汇编·学习
qq_386322695 小时前
华为网路设备学习-33(BGP协议 八)BGP路由 选路规则
学习·华为
xy_recording6 小时前
学习番外:Docker和K8S理解
学习·docker·kubernetes
鱼嘻6 小时前
西嘎嘎学习 - C++ 继承 - Day 10
开发语言·c++·学习·算法
Hello_Embed6 小时前
STM32HAL 快速入门(二十四):I2C 编程(一)—— 从 OLED 显示初识 I2C 协议
c语言·stm32·单片机·嵌入式硬件·学习