使用 Java 代码实现简单的 RabbitMQ 示例

该文章已生成可运行项目,

RabbitMQ
本文是博主在梳理 RabbitMQ 知识的过程中,将所遇到和可能会遇到的基础知识记录下来,用作梳理 RabbitMQ 的整体架构和功能的线索文章,通过查找对应的知识能够快速的了解对应的知识而解决相应的问题。


一、核心组件说明

本示例基于 RabbitMQ 默认直连交换机( Default Direct Exchange )实现基础消息通信,展示生产消费模型的核心流程。

  • 生产者(Producer):消息创建与发送方
  • 消费者(Consumer):消息接收与处理方
  • 消息队列(Queue):消息存储容器
  • 默认交换机:系统预置直连交换机(名称为空字符串)

二、生产者实现

public class Producer {
    // 核心配置参数
    private static final String QUEUE_NAME = "my-mq-queue";
    private static final String HOST = "10.106.182.54";
    private static final String USERNAME = "root";
    private static final String PASSWORD = "123456";
    private static final String EXCHANGE_NAME = "";  // 使用默认直连交换机

    public static void main(String[] args) {
        // 1. 创建连接工厂
        ConnectionFactory factory = new ConnectionFactory();
        factory.setHost(HOST);
        factory.setUsername(USERNAME);
        factory.setPassword(PASSWORD);

        try (
            // 2. 建立TCP连接(自动关闭)
            Connection connection = factory.newConnection();
            // 3. 创建信道(自动关闭)
            Channel channel = connection.createChannel()
        ) {
            // 4. 声明队列(参数需与消费者一致)
            Map<String, Object> queueArgs = new HashMap<>();
            queueArgs.put("x-message-ttl", 10000);  // 消息10秒过期
            channel.queueDeclare(QUEUE_NAME, 
                false,   // 非持久化队列
                false,   // 非排他队列
                true,    // 自动删除队列(无消费者时自动删除)
                queueArgs
            );
            
            // 5. 构造并发送消息
            String message = "Hello, How are you";
            channel.basicPublish(
                EXCHANGE_NAME,  // 使用默认交换机
                QUEUE_NAME,     // 路由键=队列名(直连交换机特性)
                null,          // 消息属性(优先级、过期时间等)
                message.getBytes()
            );
            System.out.println("[Producer] 消息发送成功");
        } catch (IOException e) {
            throw new RuntimeException("消息发送失败", e);
        }
    }
}

三、消费者实现

public class Consumer {
    // 配置与生产者保持严格一致
    public static final String QUEUE_NAME = "my-mq-queue";
    // ...其他配置同生产者...

    public static void main(String[] args) {
        ConnectionFactory factory = new ConnectionFactory();
        factory.setHost(HOST);
        factory.setUsername(USERNAME);
        factory.setPassword(PASSWORD);

        try {
            // 建立长连接
            Connection connection = factory.newConnection();
            Channel channel = connection.createChannel();
            
            // 声明队列(参数必须与生产者完全一致)
            Map<String, Object> queueArgs = new HashMap<>();
            queueArgs.put("x-message-ttl", 10000);
            channel.queueDeclare(QUEUE_NAME, false, false, true, queueArgs);

            // 创建消息回调处理器
            DeliverCallback callback = (consumerTag, delivery) -> {
                String message = new String(delivery.getBody(), StandardCharsets.UTF_8);
                System.out.printf("[Consumer] 接收到消息 | 标签:%s | 内容:%s%n", 
                    delivery.getEnvelope().getDeliveryTag(), message);
            };

            // 启动消息监听(推模式)
            channel.basicConsume(
                QUEUE_NAME, 
                true,       // 自动确认(收到即确认)
                callback, 
                consumerTag -> {}
            );
            System.out.println("[Consumer] 已启动消息监听");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

四、关键代码解析

1、队列声明(queueDeclare)

channel.queueDeclare(QUEUE_NAME, durable, exclusive, autoDelete, arguments);
  • durable:队列持久化(服务重启后保留)
  • exclusive:排他队列(仅当前连接可见,连接关闭后自动删除)
  • autoDelete:自动删除(当最后一个消费者取消订阅时删除)
  • arguments:扩展参数(消息TTL、死信配置等)

2、消息发布(basicPublish)

channel.basicPublish(exchange, routingKey, props, body);
  • 使用默认交换机时,也就是直连交换机,routingKey 必须与队列名一致
  • 消息属性(props)可设置优先级、过期时间等元信息

3、消息消费模式

  • 推模式(Push)basicConsume 实时接收消息(推荐)
  • 拉模式(Pull)basicGet 主动轮询获取消息

五、注意事项

  • 队列参数一致性:生产者和消费者声明队列时参数必须完全一致,否则会抛出参数不匹配异常,建议将队列配置参数提取为常量类统一管理。
  • 使用 try-with-resources 自动关闭连接和通道,消费者建议保持长连接,避免频繁创建销毁。
  • 消息确认机制:示例使用自动确认(autoAck=true),存在消息丢失风险,生产环境建议采用手动确认。
    channel.basicConsume(QUEUE_NAME, false, callback, ...);
    // 处理完成后手动确认
    channel.basicAck(deliveryTag, false);
    
  • 默认交换机特性:将消息直接路由到与routingKey同名的队列,队列自动绑定到默认交换机(routingKey=队列名)。

六、扩展实践建议

  • 消息持久化:

    // 消息属性设置持久化
    AMQP.BasicProperties props = new AMQP.BasicProperties.Builder()
        .deliveryMode(2)  // 持久化消息
        .build();
    
  • QoS预取控制:

    channel.basicQos(10);  // 每次预取10条消息
    
  • 死信队列配置:

    Map<String, Object> args = new HashMap<>();
    args.put("x-dead-letter-exchange", "dlx.exchange");
    channel.queueDeclare("business.queue", true, false, false, args);
    

本示例展示了 RabbitMQ 最基础的通信模型,实际生产环境中建议根据业务需求选择合适的交换机类型、完善消息确认机制,并结合 Spring AMQP 等框架进行工程化实现。

本文章已经生成可运行项目
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值