rabbitMQ confirm 模式比事务模式效率高且支持单次批量和异步三种方式。
- 单次模式批
// 单次模式 channel.confirmSelect(); channel.basicPublish(EXCHANGE_NAME, "debug", MessageProperties.PERSISTENT_TEXT_PLAIN,message.getBytes()); if (!channel.waitForConfirms()) { System.out.println("发送失败处理你的失败逻辑"); } //结束
- 批量模式
// 批量模式 批量模式如果失败要批量重新发送 channel.confirmSelect(); for (int i = 0; i < 30; i++) { channel.basicPublish(EXCHANGE_NAME, "debug", MessageProperties.PERSISTENT_TEXT_PLAIN, (message + i).getBytes()); } if (!channel.waitForConfirms()) { System.out.println("发送失败处理你的失败逻辑"); } // 批量模式结束
- 异步模式:需要注意的是异步返回的消息的id 如果服务器插入了多条返回来的是最大的一条消息id
// 异步开启confirm SortedSet<Long> confirmSet = Collections.synchronizedSortedSet(new TreeSet<Long>()); channel.confirmSelect(); channel.addConfirmListener(new ConfirmListener() { public void handleAck(long deliveryTag, boolean multiple) throws IOException { // multiple 是true 表示成功了插入了多个消息返回最后一个消息的id if (multiple) { // clear 清除 最后一个消息之前的队列 confirmSet.headSet(deliveryTag + 1).clear(); } else { confirmSet.remove(deliveryTag); } } public void handleNack(long deliveryTag, boolean multiple) throws IOException { System.out.println("Nack, SeqNo: " + deliveryTag + ", multiple: " + multiple); // multiple 是true 表示失败了多个消息返回最后一个消息的id if (multiple) { // clear 清除 最后一个消息之前的队列 confirmSet.headSet(deliveryTag + 1).clear(); } else { confirmSet.remove(deliveryTag); } //注意这里需要添加处理消息重发的场景 } }); while (true) { // 每次发送一个消息 加入到队列一个消息id long nextSeqNo = channel.getNextPublishSeqNo(); channel.basicPublish(EXCHANGE_NAME, "debug", MessageProperties.PERSISTENT_TEXT_PLAIN, message.getBytes()); confirmSet.add(nextSeqNo); }