RabbitMQ消息发布确任的三种方式

RabbitMQ消息发布确任的三种方式

单个确认

顾名思义就是消息生产方每发送一条消息,服务器都需要返回一条确认消息。

优点:每条消息都会进行确认,消息发送失败可以快速定位失败消息。

缺点:效率低

/**
     * 单个确认.
     *
     * @throws Exception Exception
     */
    public static void publishMessageIndividually() throws Exception {
        Channel channel = RabbitMqUtils.getChannel();

        String queueName = UUID.randomUUID().toString();
        channel.queueDeclare(queueName, true, false, false, null);
        channel.confirmSelect();

        long begin = System.currentTimeMillis();
        for (int i = 0; i < MESSAGE_COUNT; i++) {
            String message = i + "Wk";
            channel.basicPublish("", queueName, null, message.getBytes(StandardCharsets.UTF_8));
            boolean flag = channel.waitForConfirms();
            if (flag) {
                System.out.println("消息发送成功");
            }
        }
        long end = System.currentTimeMillis();
        System.out.println("发布1000个单独确认消息耗时:" + (end - begin));
    }
}

批量确认

可以设定生产方每发送n条消息,服务器返回一条确认信息。

优点:效率高

缺点:一旦出现消息发送失败,不容易确定是哪一条失败。

/**
 * 批量发布确认.
 *
 * @throws Exception Exception
 */
public static void publishMessageBatch() throws Exception {
    Channel channel = RabbitMqUtils.getChannel();

    String queueName = UUID.randomUUID().toString();
    channel.queueDeclare(queueName, true, false, false, null);
    channel.confirmSelect();
    long begin = System.currentTimeMillis();

    //批量确认消息的长度.

    int batchSize = 100;

    for (int i = 0; i < MESSAGE_COUNT; i++) {
        String message = i + "Wk";
        channel.basicPublish("", queueName, null, message.getBytes(StandardCharsets.UTF_8));
        if (i % batchSize == 0) {
            channel.waitForConfirms();
        }
    }

    long end = System.currentTimeMillis();
    System.out.println("发布1000个批量确认消息耗时:" + (end - begin));
}

异步批量确认

即发送方不必等待上一条确认消息返回才开始发送下一条,确认消息和发送消息是异步行为。也是每条消息都进行确认。

优点:可以达到最佳的性能和资源使用,在出现问题的情况下可以很好地控制。

缺点:实现稍微难一点。

/**
 * 异步确认.
 *
 * @throws Exception Exception
 */
public static void publishMessageAsync() throws Exception {
    Channel channel = RabbitMqUtils.getChannel();

    String queueName = UUID.randomUUID().toString();
    channel.queueDeclare(queueName, true, false, false, null);
    channel.confirmSelect();
    /**
     * 线程安全有序的一个map,适用于高并发的情况.
     */
    ConcurrentSkipListMap<Long, String> concurrentSkipListMap =
            new ConcurrentSkipListMap<>();
    //消息确认成功回调
    ConfirmCallback ackCallBack = (deliveryTag, multiple) -> {
        if (multiple) {
            ConcurrentSkipListMap<Long, String> confirmMap =
                    (ConcurrentSkipListMap<Long, String>) concurrentSkipListMap.headMap(deliveryTag);
            confirmMap.clear();
        }else {
            concurrentSkipListMap.remove(deliveryTag);
        }
        System.out.println("确认的消息:" + deliveryTag);
    };

    //消息确认失败回调
    ConfirmCallback nackCallBack = (deliveryTag, multiple) -> {
        String message = concurrentSkipListMap.get(deliveryTag);
        System.out.println("未确认的消息:" + deliveryTag);
        try {
            Thread.sleep(10000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    };
    //消息的监听器,监听异步回调的信息.
    channel.addConfirmListener(ackCallBack, nackCallBack);


    long begin = System.currentTimeMillis();
    //批量发消息.
    for (int i = 0; i < MESSAGE_COUNT; i++) {
        String message = i + "Wk";
        channel.basicPublish("", queueName, null, message.getBytes(StandardCharsets.UTF_8));
        System.out.println(i);
        concurrentSkipListMap.put(channel.getNextPublishSeqNo(), message);
    }

    long end = System.currentTimeMillis();
    System.out.println("发布1000个异步确认消息耗时:" + (end - begin));
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
RabbitMQ消息有以下几种方式: 1. 简单模式(Simple Mode):在简单模式下,生产者直接将消息发送到队列中,消费者从队列中接收消息。这种方式是最简单的方式,适用于简单的场景。 2. 工作队列模式(Work Queue Mode):在工作队列模式下,生产者将消息发送到一个队列中,多个消费者同时监听这个队列,每个消息只能被一个消费者接收。这种方式可以实现任务的并发处理。 3. 发布/订阅模式(Publish/Subscribe Mode):在发布/订阅模式下,生产者将消息发送到一个交换机(Exchange)中,交换机将消息广播给所有绑定到它的队列。每个消费者都会接收到交换机发送的消息。这种方式适用于需要将消息广播给多个消费者的场景。 4. 路由模式(Routing Mode):在路由模式下,生产者将消息发送到一个交换机中,并指定一个路由键(Routing Key),消费者根据路由键来选择接收哪些消息。这种方式可以实现消息的有选择性地发送给特定的消费者。 5. 主题模式(Topic Mode):在主题模式下,生产者将消息发送到一个交换机中,并指定一个主题(Topic),消费者可以使用通配符来匹配主题,选择接收哪些消息。这种方式可以实现更灵活的消息过滤和选择。 6. 高级模式(Advanced Mode):除了以上几种常见的方式RabbitMQ 还提供了一些高级的消息发送方式,如消息持久化、消息优先级、消息过期等。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值