2.2 Return消息機制

Return Listener用於處理一些不可路由的消息!
我們的消息生產者,通過指定一個ExChange和Routingkey,把消息送達到某一個隊列種去,然後我們的消費者監聽隊列,進行消費處理操作!
但是在某些情況下,如果我們在發送消息的時候,當前的Exchange不存在或者指定的路由key路由不到,這個時候如果我們需要監聽種不可達的消息,就要使用Return Listener!
在基礎的API種有一個關鍵的配置項:Mandatory:如果爲true,則監聽器會接受到路由不可達的消息,然後進行後續處理,如果爲false,那麼broker端自動刪除該消息!
在這裏插入圖片描述
消費者代碼

package com.star.movie.returnlistener;

import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.QueueingConsumer;
import com.star.movie.common.Constant;
import com.rabbitmq.client.QueueingConsumer.Delivery;

/**
 * @Description:消費者
 * @author:kaili
 * @Date: 2019-04-22 17:41
 **/
public class ReturnConsumer  {
    public static void main(String[] args) throws Exception{
        Connection connection = Constant.getConnection();
        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.queueDeclare(queueName, true, false, false, null);
        channel.queueBind(queueName, exchangeName, routingKey);

        QueueingConsumer queueingConsumer = new QueueingConsumer(channel);

        channel.basicConsume(queueName, true, queueingConsumer);

        while(true){

            Delivery delivery = queueingConsumer.nextDelivery();
            String msg = new String(delivery.getBody());
            System.err.println("消費者: " + msg);
        }
    }
}

生產者代碼快

package com.star.movie.returnlistener;

import com.rabbitmq.client.AMQP;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ReturnListener;
import com.star.movie.common.Constant;

import java.io.IOException;

/**
 * @Description:生產者
 * @author:kaili
 * @Date: 2019-04-22 17:41
 **/
public class ReturnProducer {

    public static void main(String[] args) throws Exception{
        Connection connection = Constant.getConnection();
        Channel channel = connection.createChannel();
        String exchange = "test_return_exchange";
        String routingKey = "return.save";
        String routingKeyError = "abc.save";

        String msg = "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.err.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("properties: " + properties);
                System.err.println("body: " + new String(body));
            }
        });
        //發送送達不到的消息mandatory屬性爲true
//        channel.basicPublish(exchange, routingKeyError, false, null, msg.getBytes());
        //發送送達不到的消息mandatory屬性爲false
        channel.basicPublish(exchange, routingKeyError, true, null, msg.getBytes());
        //發送正常消息
//        channel.basicPublish(exchange, routingKey, true, null, msg.getBytes());
    }
}

step 1 啓動消費者代碼
生成test_return_exchange交換機,綁定test_return_queue隊列,綁定健爲return.#,類型爲topic
在這裏插入圖片描述

step 2 啓動消費者代碼
使用發送送達不到的消息mandatory屬性爲false這種發送方式,觀察控制檯打印消息。在這裏插入圖片描述
消息發送失敗,沒有路由到對應的隊列,在return監聽代碼中打印了相關消息路由的消息。

step 3 修改消費者代碼再次啓動
使用發送送達不到的消息mandatory屬性爲true這種發送方式,觀察控制檯打印消息。
在這裏插入圖片描述
生產者控制檯沒有任何消息
觀察消費者控制檯
在這裏插入圖片描述
消費者控制檯也沒有任何消息,說明該消息未發送到Broker,return監聽也未接收到任何消息。這是因爲Mandatory屬性設置開啓和關閉不同下的不同處理結果。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章