RabbitMQ的Direct Exchange模式实现的消息发布案例

Producer生产者代码

java 复制代码
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;

public class RabbitMQProducer {

    private final static String EXCHANGE_NAME = "direct_message_exchange";
    private final static String EXCHANGE_TYPE = "direct";
    
    public static void main(String[] args) {
        // 1. 创建连接工厂,设置连接参数
        ConnectionFactory connectionFactory = new ConnectionFactory();
        connectionFactory.setHost("localhost");
        connectionFactory.setPort(5672); // RabbitMQ默认端口
        connectionFactory.setUsername("guest");
        connectionFactory.setPassword("guest");

        try (Connection connection = connectionFactory.newConnection();
             Channel channel = connection.createChannel()) {

            // 2. 声明交换机 (direct类型,持久化)
            channel.exchangeDeclare(EXCHANGE_NAME, EXCHANGE_TYPE, true);

            // 3. 声明队列 (持久化,非独占,连接断开时不自动删除)
            channel.queueDeclare("queue5", true, false, false, null);
            channel.queueDeclare("queue6", true, false, false, null);
            channel.queueDeclare("queue7", true, false, false, null);

            // 4. 绑定队列到交换机,设置路由键
            channel.queueBind("queue5", EXCHANGE_NAME, "order");
            channel.queueBind("queue6", EXCHANGE_NAME, "order");
            channel.queueBind("queue7", EXCHANGE_NAME, "course");

            // 5. 准备要发送的消息
            String message = "你好,学相伴:www.kuangstudy.com";

            // 6. 向交换机发送消息,使用路由键 "course"
            channel.basicPublish(EXCHANGE_NAME, "course", null, message.getBytes("UTF-8"));
            System.out.println("消息发送成功!");

        } catch (Exception ex) {
            // 捕获异常并打印堆栈信息
            ex.printStackTrace();
            System.out.println("消息发送出现异常...");
        } finally {
            // 在try-with-resources中,不再需要显式关闭连接和通道
            // 会自动关闭连接和通道
        }
    }
}

功能点:

  1. 声明了一个Direct类型的交换机 ,并绑定了三个队列(queue5queue6queue7)。其中queue5queue6都绑定到order路由键,而queue7绑定到course路由键。
  2. 发送了一条消息到course路由键绑定的队列中(即queue7)。

Consumer消费者代码

java 复制代码
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.DeliverCallback;

public class RabbitMQConsumer {

    private final static String QUEUE_NAME = "queue7"; // 与生产者的绑定一致
    private final static String EXCHANGE_NAME = "direct_message_exchange";
    private final static String EXCHANGE_TYPE = "direct";
    
    public static void main(String[] args) {
        // 1. 创建连接工厂,设置连接参数
        ConnectionFactory connectionFactory = new ConnectionFactory();
        connectionFactory.setHost("localhost");
        connectionFactory.setPort(5672); // RabbitMQ默认端口
        connectionFactory.setUsername("guest");
        connectionFactory.setPassword("guest");

        try (Connection connection = connectionFactory.newConnection();
             Channel channel = connection.createChannel()) {

            // 2. 声明交换机和队列,与生产者保持一致
            channel.exchangeDeclare(EXCHANGE_NAME, EXCHANGE_TYPE, true);
            channel.queueDeclare(QUEUE_NAME, true, false, false, null);

            // 3. 绑定队列到交换机,路由键为"course"
            channel.queueBind(QUEUE_NAME, EXCHANGE_NAME, "course");

            System.out.println(" [*] 等待接收消息...");

            // 4. 定义接收消息的回调函数
            DeliverCallback deliverCallback = (consumerTag, delivery) -> {
                String message = new String(delivery.getBody(), "UTF-8");
                System.out.println(" [x] 接收到的消息: '" + message + "'");
                
                // 这里可以添加进一步的消息处理逻辑
            };

            // 5. 开始消费消息 (自动应答)
            channel.basicConsume(QUEUE_NAME, true, deliverCallback, consumerTag -> { });

        } catch (Exception ex) {
            // 捕获异常并打印堆栈信息
            ex.printStackTrace();
            System.out.println("消费者运行中出现异常...");
        }
    }
}

功能点:

1. 与生产者保持一致 :消费者的队列名称、交换机名称和路由键与生产者保持一致,即监听queue7队列,并接收路由键为course的消息。

2. 回调函数处理消息 :使用DeliverCallback来定义收到消息后的处理逻辑。在回调函数中,delivery.getBody()获取消息内容,随后可以对消息进行处理、存储或其他业务逻辑操作。

3 自动应答basicConsume中的true表示自动应答(auto-acknowledge),即消息处理完毕后,RabbitMQ会自动确认消息已成功处理。如果需要手动应答,可以将true替换为false,并在处理完成后调用channel.basicAck()来手动确认消息。

相关推荐
KmSH8umpK11 小时前
Redis分布式锁从原生手写到Redisson高阶落地,附线上死锁复盘优化方案进阶第三篇
redis·分布式·wpf
Dontla14 小时前
aio-pika介绍(基于asyncio的Python异步消息队列客户端,用于操作RabbitMQ,并实现对AMQP协议支持)
python·rabbitmq·ruby
KmSH8umpK14 小时前
SpringBoot 分布式锁实战:从单机锁到Redis分布式锁全覆盖,解决超卖、重复下单、幂等并发问题
spring boot·redis·分布式
KmSH8umpK17 小时前
Redis分布式锁从原生手写到Redisson高阶落地,附线上死锁复盘优化方案
redis·分布式·wpf
_F_y19 小时前
仿RabbitMQ实现消息队列-服务端核心模块实现(3)
c++·算法·rabbitmq
长河19 小时前
XXL-JOB 从本地快速上手到核心架构深度解析
分布式
juniperhan19 小时前
Flink 系列第22篇:Flink SQL 参数配置与性能调优指南:从 Checkpoint 到聚合优化
大数据·数据仓库·分布式·sql·flink
juniperhan1 天前
Flink 系列第21篇:Flink SQL 函数与 UDF 全解读:类型推导、开发要点与 Module 扩展
java·大数据·数据仓库·分布式·sql·flink
marsh02062 天前
41 openclaw分布式会话管理:跨服务状态同步方案
分布式·ai·编程·技术
杰建云1672 天前
Plurai 分布式推理引擎深度评测
分布式