rabbitmq
版本:3.8.3
amqp-client
版本:5.7.1
生产者消息确认机制(Publisher Confirms
) 是rabbitmq
为了确保消息的成功发送而提供的一种扩展能力。当在channel
上开启了confirm
机制,那么消息生产者将会在消息发送之后异步地确认消息是否成功发送到rabbitmq
。
- 生产者将信道设置成
confirm
模式,一旦信道进入confirm
模式,所有在该信道上面发布的消息都会被指派一个唯一的ID
(从1
开始),一旦消息被投递到所有匹配的队列之后,RabbitMQ
就会发送一个确认(Basic.Ack
)给生产者(包含消息的唯一ID
),生产者便能知晓消息是否已经正确地到达了目的地。- 消息确认是异步的。生产者发送一条消息之后,可以在等待信道返回确认的同时继续发送下一条消息,当消息最终得到确认之后,生产者可以通过回调方法来处理这条确认消息。
- 如果
RabbitMQ
因为自身内部错误导致消息丢失,就会发送一条nack
(Basic.Nack
)命令给生产者,生产者可以在回调中处理它。- 不会出现一条消息即被
ack
,又被nack
的情况。
rabbitmq
提供了三种确认方式:
channel.waitForConfirms()
—— 单个消息确认(同步)channel.waitForConfirmsOrDie()
—— 批量消息确认(同步)channel.addConfirmListener()
—— 异步消息确认(异步)
1 三种确认方式
1.1 单个消息确认
在发送单个消息前,通过channel.confirmSelect()
开启消息确认机制。在发送消息之后,通过channel.waitForConfirms(long timeout)
同步等待消息的确认,可以设置超时时间。
/**
* 生产者
*/
public class Producer {
public static final String EXCHANGE_CONFIRM_SINGLE = "exchange-confirm-single";
public static void main(String[] args) {
// 1、创建连接工厂
ConnectionFactory factory = new ConnectionFactory();
factory.setHost("192.168.99.100");
factory.setPort(5672);
factory.setUsername("admin");
factory.setPassword("password");
// 2、获取连接、通道
try (Connection connection = factory.newConnection();
Channel channel = connection.createChannel()) {
// 3、声明发送将要发送到哪个exchange
channel.exchangeDeclare(EXCHANGE_CONFIRM_SINGLE, BuiltinExchangeType.FANOUT);