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