RabbitMQ事务机制和确认机制

文章目录

生产者:RabbitMQ提供transaction和confirm模式来确保生产者不丢消息

● 通过事务实现

● 通过发送方确认机制(publisher confirm)实现

1.1事务机制:发送消息前,开启事务(channel.txSelect()),然后发送消息,如果发送过程中出现什么异常,事务就会回滚(channel.txRollback()),如果发送成功则提交事务(channel.txCommit())。这种方式有个缺点:吞吐量下降;

事务实现

● channel.txSelect(): 将当前信道设置成事务模式

● channel.txCommit(): 用于提交事务

● channel.txRollback(): 用于回滚事务

通过事务实现机制,只有消息成功被rabbitmq服务器接收,事务才能提交成功,否则便可在捕获异常之后进行回滚,然后进行消息重发,但是事务非常影响rabbitmq的性能。还有就是事务机制是阻塞的过程,只有等待服务器回应之后才会处理下一条消息

confirm模式用的居多

一旦channel进入confirm模式,所有在该信道上发布的消息都将会被指派一个唯一的ID(从1开始),一旦消息被投递到所有匹配的队列之后;rabbitMQ就会发送一个ACK给生产者(包含消息的唯一ID),这就使得生产者知道消息已经正确到达目的队列了;如果rabbitMQ没能处理该消息,则会发送一个Nack消息给你,你可以进行重试操作。

confirm方式有三种模式:普通confirm模式、批量confirm模式、异步confirm模式

channel.confirmSelect(): 将当前信道设置成了confirm模式

普通confirm模式

每发送一条消息,就调用waitForConfirms()方法,等待服务端返回Ack或者nack消息

RabbitMQ 事务机制

RabbitMQ 提供了事务机制来确保消息的可靠性传递。使用事务机制时,可以在发送消息之前开启一个事务,在事务内发送消息并进行确认提交,以确保消息被正确地发送到 RabbitMQ 中。

下面是使用 RabbitMQ 事务机制发送消息的一般步骤:

  1. 开启事务:通过 tx_select() 方法开启一个事务。
  2. 发送消息:在事务内使用 basic_publish() 方法发送消息到指定的 Exchange 和队列。
  3. 提交事务:通过 tx_commit() 方法提交事务,确保在事务内的操作生效。
  4. 回滚事务(可选):如果发送消息过程中出现异常或错误,可以通过 tx_rollback() 方法回滚事务,撤销事务内的操作。
    当使用 Java 编程语言与 RabbitMQ 一起使用时,您可以通过以下步骤来使用 RabbitMQ 的事务机制:
java 复制代码
1. 创建 RabbitMQ 连接和信道:
ConnectionFactory factory = new ConnectionFactory();
factory.setHost("localhost");
Connection connection = factory.newConnection();
Channel channel = connection.createChannel();
2. 开启事务:
channel.txSelect();
3. 发布消息到队列:
String message = "Hello, RabbitMQ!";
channel.basicPublish("", "queue_name", null, message.getBytes());
4. 提交事务:
channel.txCommit();
System.out.println("Message sent successfully");
5. 回滚事务(可选):
channel.txRollback();
System.out.println("Failed to send message");
需要注意的是,在使用事务机制时,如果发生异常或错误,您可以选择回滚事务以撤销之前的操作,或者提交事务以确认消息的发送。
下面是一个完整的示例代码,演示了如何在 Java 中使用 RabbitMQ 的事务机制:
import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.Channel;

public class RabbitMqTransactionExample {
    private static final String QUEUE_NAME = "queue_name";

    public static void main(String[] args) {
        try {
            ConnectionFactory factory = new ConnectionFactory();
            factory.setHost("localhost");
            Connection connection = factory.newConnection();
            Channel channel = connection.createChannel();

            // 开启事务
            channel.txSelect();

            String message = "Hello, RabbitMQ!";

            // 发布消息到队列
            channel.basicPublish("", QUEUE_NAME, null, message.getBytes());

            // 提交事务
            channel.txCommit();
            System.out.println("Message sent successfully");
        } catch (Exception e) {
            // 回滚事务
            channel.txRollback();
            System.out.println("Failed to send message");
            e.printStackTrace();
        }
    }
}

请注意,事务机制会对性能产生一定的影响,因为它需要进行额外的操作来维护事务的一致性。在高并发场景下,使用事务可能会导致性能下降。因此,在选择使用事务机制时,请根据实际需求和性能要求进行权衡。

需要注意的是,事务机制会对性能产生一定的影响,因为它需要进行额外的操作来维护事务的一致性。在高并发场景下,使用事务可能会导致性能下降。因此,在选择使用事务机制时,请根据实际需求和性能要求进行权衡。

总的来说,事务机制提供了一种确保消息传递可靠性的方法,但在实际应用中需要慎重考虑其对性能的影响。在大部分情况下,使用确认机制(Publisher Confirm)已经能够满足消息传递的可靠性要求,并且对性能影响较小。

RabbitMQ确认机制

RabbitMQ 的确认机制(Publisher Confirm)是一种用于确保消息可靠发送的机制。通过确认机制,生产者可以在消息被成功投递到 RabbitMQ Broker 后得到确认,从而确保消息已经安全地保存在 Broker 中,而不是在传输过程中丢失。

使用确认机制时,需要将信道(channel)设置为 confirm 模式,然后在发送消息后等待确认。确认可以是单条消息的确认,也可以是批量消息的确认。

当使用 Java 编程语言与 RabbitMQ 一起使用时,您可以使用 RabbitMQ 的确认机制(Publisher Confirm)来确保消息的可靠发送。以下是使用 RabbitMQ 确认机制的一般步骤:

java 复制代码
1. 创建 RabbitMQ 连接和信道:
ConnectionFactory factory = new ConnectionFactory();
factory.setHost("localhost");
Connection connection = factory.newConnection();
Channel channel = connection.createChannel();
2. 设置信道为确认模式:
channel.confirmSelect();
3. 发布消息到队列:
String message = "Hello, RabbitMQ!";
channel.basicPublish("", "queue_name", null, message.getBytes());
4. 等待确认:
if (channel.waitForConfirms()) {
    System.out.println("Message sent successfully");
} else {
    System.out.println("Failed to send message");
}

在上述代码中,我们首先创建了 RabbitMQ 连接和信道。然后,通过 channel.confirmSelect() 将信道设置为确认模式。接下来,我们使用 basicPublish() 方法发布消息到指定的队列。最后,通过 channel.waitForConfirms() 等待消息的确认,如果成功确认,则输出 "Message sent successfully",否则输出 "Failed to send message"。
请注意,RabbitMQ 的确认机制支持批量确认,即可以一次确认多条消息。您可以在 basicPublish() 方法之前调用 channel.getNextPublishSeqNo() 获取当前消息的序列号,然后在 waitForConfirms() 方法中使用 channel.waitForConfirms(sequenceNumber) 来等待指定序列号之前的所有消息确认。
以下是一个完整的示例代码,演示了如何在 Java 中使用 RabbitMQ 的确认机制:
import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.Channel;

public class RabbitMqConfirmExample {
    private static final String QUEUE_NAME = "queue_name";

    public static void main(String[] args) {
        try {
            ConnectionFactory factory = new ConnectionFactory();
            factory.setHost("localhost");
            Connection connection = factory.newConnection();
            Channel channel = connection.createChannel();

            // 设置信道为确认模式
            channel.confirmSelect();

            String message = "Hello, RabbitMQ!";

            // 发布消息到队列
            channel.basicPublish("", QUEUE_NAME, null, message.getBytes());

            // 等待确认
            if (channel.waitForConfirms()) {
                System.out.println("Message sent successfully");
            } else {
                System.out.println("Failed to send message");
            }
        } catch (Exception e) {
            System.out.println("Failed to send message");
            e.printStackTrace();
        }
    }
}

确认机制是一种轻量且高效的方式来确保消息的可靠性传递。相比于事务机制,确认机制对性能的影响较小,因此在大多数情况下推荐使用确认机制。

相关推荐
drebander16 分钟前
使用 Java Stream 优雅实现List 转化为Map<key,Map<key,value>>
java·python·list
乌啼霜满天24919 分钟前
Spring 与 Spring MVC 与 Spring Boot三者之间的区别与联系
java·spring boot·spring·mvc
tangliang_cn25 分钟前
java入门 自定义springboot starter
java·开发语言·spring boot
程序猿阿伟25 分钟前
《智能指针频繁创建销毁:程序性能的“隐形杀手”》
java·开发语言·前端
Grey_fantasy35 分钟前
高级编程之结构化代码
java·spring boot·spring cloud
弗锐土豆42 分钟前
工业生产安全-安全帽第二篇-用java语言看看opencv实现的目标检测使用过程
java·opencv·安全·检测·面部
Elaine20239143 分钟前
零碎04 MybatisPlus自定义模版生成代码
java·spring·mybatis
小小大侠客1 小时前
IText创建加盖公章的pdf文件并生成压缩文件
java·pdf·itext
一二小选手1 小时前
【MyBatis】全局配置文件—mybatis.xml 创建xml模板
xml·java·mybatis
猿java1 小时前
Linux Shell和Shell脚本详解!
java·linux·shell