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,适用于广播场景。
相关推荐
笨鸟先飞的橘猫1 分钟前
树结构在游戏行业中的应用
学习·游戏
yangmu32031 小时前
从显像管到Micro-LED:屏幕的光之进化
学习·显示器
半生过往2 小时前
前端工程师学习智能体开发(一)
前端·学习·状态模式
m4Rk_4 小时前
【论文阅读】Agent 记忆机制(67):MemPO——用记忆级信用分配训练 Agent 主动管理长程上下文
论文阅读·人工智能·学习·开源·github
下辈子不要当码农4 小时前
ARM学习(1)
学习·arm
東隅已逝,桑榆非晚4 小时前
vector(模拟实现)
c++·笔记·学习
鱼听禅5 小时前
C# 学习笔记-使用 类型化客户端搭建HTTP客户端服务
学习·http·c#·工厂方法模式
高亦真5 小时前
今天是学习嵌入式的第38天
linux·学习·算法
传奇开心果编程5 小时前
【Rust入门知识点学与练】第33课:异步编程入门(async/await)强化
开发语言·学习·rust
传奇开心果编程6 小时前
【Rust入门知识点学与练】第34课:所有权与借用
开发语言·学习·rust