Return Listener 用於處理一些不可路由的消息
消息生產者通過制定一個Exchane和RoutingKey,把消息送達到某一個隊列中去;消費者監聽隊列進行消費處理。
但是在某些情況下,發送消息的時候,當前Exchange不存在或制定的路由key不存在,這時我們需要監聽這種不可達的消息。用到的就是Return Listener。
1.API中關鍵項配置
Mandatory:true 監聽器會接收到路由不可達的消息,在進行後續處理;
false MQ服務端將自動刪除該消息;
2.代碼實現
package com.lfv.rabbitmq.api.returnlistener;
import java.io.IOException;
import java.util.concurrent.TimeoutException;
import com.rabbitmq.client.AMQP;
import com.rabbitmq.client.AMQP.BasicProperties;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.ReturnListener;
public class Producer {
public static void main(String[] args) throws IOException, TimeoutException {
ConnectionFactory connectionFactory = new ConnectionFactory();
connectionFactory.setHost("192.168.0.10");
connectionFactory.setPort(5672);
connectionFactory.setUsername("admin");
connectionFactory.setPassword("admin");
connectionFactory.setVirtualHost("/");
//2獲取Connection
Connection connection = connectionFactory.newConnection();
Channel channel = connection.createChannel();
String exchange = "test_return_exchange";
String routingKey = "return.save";
String routingKeyError="abc.save";
String sendmsg ="Hello RabbitMQ return Message";
channel.addReturnListener(new ReturnListener() {
@Override
public void handleReturn(int replyCode, String replyText
, String exchange, String routingKey
, AMQP.BasicProperties properties, byte[] body)
throws IOException {
System.out.println("***************Handle Return*********************");
System.err.println("replyCode:"+replyCode);
System.err.println("replyText:"+replyText);
System.err.println("exchange:"+exchange);
System.err.println("routingKey:"+routingKey);
System.err.println("AMQP.BasicProperties:"+properties);
System.err.println("body:"+new String(body));
}
});
channel.basicPublish(exchange, routingKey, true, null, sendmsg.getBytes());
}
}
package com.lfv.rabbitmq.api.returnlistener;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.QueueingConsumer;
import com.rabbitmq.client.QueueingConsumer.Delivery;
public class Consumer {
public static void main(String[] args) throws Exception{
ConnectionFactory connectionFactory = new ConnectionFactory();
connectionFactory.setHost("192.168.0.10");
connectionFactory.setPort(5672);
connectionFactory.setUsername("admin");
connectionFactory.setPassword("admin");
connectionFactory.setVirtualHost("/");
Connection connection = connectionFactory.newConnection();
Channel channel = connection.createChannel();
String exchangeName = "test_return_exchange";
String routingKey = "return.#";
String queueName ="test_return_queue";
channel.exchangeDeclare(exchangeName, "topic", true,false,null);
channel.queueDeclareNoWait(queueName, true, false, false, null);
channel.queueBind(queueName, exchangeName, routingKey);
QueueingConsumer queueingConsume = new QueueingConsumer(channel);
channel.basicConsume(queueName, true, queueingConsume);
for(;;) {
Delivery delivery = queueingConsume.nextDelivery();
String msg = new String(delivery.getBody());
System.out.println("------------- return 消費端---------------"+msg);
}
}
}
2.1消費端接收到正常的數據
2.2生產端發送錯誤返回結果
設置一個不能投遞的routingKey
String routingKeyError="abc.save";
消費端監聽到的返回結果如下:
***************Handle Return*********************
replyCode:312
replyText:NO_ROUTE
exchange:test_return_exchange
routingKey:abc.save
AMQP.BasicProperties:#contentHeader<basic>(content-type=null, content-encoding=null, headers=null, delivery-mode=null, priority=null, correlation-id=null, reply-to=null, expiration=null, message-id=null, timestamp=null, type=null, user-id=null, app-id=null, cluster-id=null)
body:Hello RabbitMQ return Message