概述
消息確認是指當生成者發送消息後,如果Server接收到消息,則會給生產者一個應答。生產者接收應答,用來確認該消息是否正常發送到Server。
在實際項目中,可以利用這一機制保障消息的可靠性投遞,如果消息未發送成功,可以在監聽事件中記錄日誌、重新發送消息等操作。
開啓Confirm消息確認機制
- 在生產者的channel上開啓確認機制:
channel.confirmSelect();
- 在channel上添加Confirm監聽事件:
channel.addConfirmListener(new ConfirmListener() ...
代碼演示
- 生產者代碼
監聽事件的兩個方法:handleAck()
消息投遞成功後回調,handleNack
消息未成功投遞迴調
public static void main(String[] args) throws Exception{
ConnectionFactory connectionFactory=new ConnectionFactory();
connectionFactory.setHost("127.0.0.1");
connectionFactory.setPort(5672);
connectionFactory.setUsername("guest");
connectionFactory.setPassword("guest");
//設置虛擬主機
connectionFactory.setVirtualHost("/");
//創建一個鏈接
Connection connection = connectionFactory.newConnection();
//創建channel
Channel channel = connection.createChannel();
//消息的確認模式
channel.confirmSelect();
String exchangeName="test_confirm_exchange";
String routeKey="confirm.test";
String msg="RabbitMQ send message confirm test!";
for (int i=0;i<5;i++){
channel.basicPublish(exchangeName,routeKey,null,msg.getBytes());
}
//確定監聽事件
channel.addConfirmListener(new ConfirmListener() {
/**
* 消息成功發送
* @param deliveryTag 消息唯一標籤
* @param multiple 是否批量
* @throws IOException
*/
@Override
public void handleAck(long deliveryTag, boolean multiple) throws IOException {
System.out.println("**********Ack*********");
}
/**
* 消息沒有成功發送
* @param deliveryTag
* @param multiple
* @throws IOException
*/
@Override
public void handleNack(long deliveryTag, boolean multiple) throws IOException {
System.out.println("**********No Ack*********");
}
});
}
- 消費者端代碼
public static void main(String[] args) throws Exception{
System.out.println("======消息接收start==========");
ConnectionFactory connectionFactory=new ConnectionFactory();
connectionFactory.setHost("127.0.0.1");
connectionFactory.setPort(5672);
connectionFactory.setUsername("guest");
connectionFactory.setPassword("guest");
//設置虛擬主機
connectionFactory.setVirtualHost("/");
//創建鏈接
Connection connection = connectionFactory.newConnection();
//創建channel
Channel channel = connection.createChannel();
String exchangeName="test_confirm_exchange";
String exchangeType="topic";
//聲明Exchange
channel.exchangeDeclare(exchangeName,exchangeType,true,false,false,null);
String queueName="test_confirm_queue";
//聲明隊列
channel.queueDeclare(queueName,true,false,false,null);
String routeKey="confirm.#";
//綁定隊列和交換機
channel.queueBind(queueName,exchangeName,routeKey);
channel.basicConsume(queueName, true, new DefaultConsumer(channel) {
@Override
public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
System.out.println("接收到消息::"+new String(body));
}
});
}