RabbitMQ消息發佈之失敗確認

AMQP及RabbitMQ概論中介紹了RabbitMQ的大致流程,其中我們提到過,當消息路由到了不存在的隊列時, 一般情況下RabbitMQ會直接將其丟棄。
在這裏插入圖片描述


不做任何配置的情況下,生產者是不知道消息是否真正到達RabbitMQ,也就是說消息發佈操作不返回任何消息給生產者。


那麼怎麼保證我們消息發佈的可靠性?這裏我們就可以啓動失敗確認,在發送消息時設置mandatory標誌,即可開啓故障檢測模式。
在這裏插入圖片描述

注意:失敗確認只會讓RabbitMQ向你通知失敗,而不會通知成功。如果消息正確路由到隊列,則發佈者不會受到任何通知。帶來的問題是無法確保發佈消息一定是成功的,因爲通知失敗的消息可能會丟失。


下面我們就來看看實際的代碼實現,首先我們需要設置上述所說的mandatory標誌,我們在發送消息時,再增加一個參數即可,如下:
在這裏插入圖片描述

上述設置好mandatory標誌後,然後我們就準備一個不存在的路由鍵發送消息(路由鍵名稱可自行填寫,只要未被消費者使用即可),另外這裏注意簡單的設置了一個睡眠2秒用於接受失敗確認的消息。


失敗確認設置完成了,那麼我們該如何來接受返回的失敗消息呢,這裏我們就需要添加一個監聽器來監聽返回的失敗消息,如下:
在這裏插入圖片描述

這裏我們就是簡單的將其返回的消息進行打印出來了,這裏可以進行相關的業務處理,然後我們就進行測試即可,這裏我們只需要啓動下生成者即可,生產者代碼如下:

public class DirectProducer {

    //交換器名稱
    public static final String EXCHANGE_NAME = "logs";

    public static void main(String[] args) throws Exception {
        //創建連接,連接到RabbitMQ
        ConnectionFactory connectionFactory = new ConnectionFactory();
        connectionFactory.setHost("127.0.0.1");
        Connection connection = connectionFactory.newConnection();

        //創建信道
        Channel channel = connection.createChannel();
        //創建交換器
        channel.exchangeDeclare(EXCHANGE_NAME, BuiltinExchangeType.DIRECT);

        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("replyText: " +replyText);
                System.out.println("exchange: " + exchange);
                System.out.println("routingKey: " + routingKey);
                System.out.println("message: " + new String(body));
            }
        });

        //定義的業務日誌消息級別,即作爲路由鍵使用
        //String[] logLevels = {"error", "warn", "info"};
        String[] logLevels = {"mandatory"};
        for (int i = 0; i < logLevels.length; i++) {
            String logLevel = logLevels[i];
            String msg = "Hello RabbitMQ";

            //發佈消息,需要參數:交換器、路由鍵,其中以日誌消息級別爲路由鍵
            //channel.basicPublish(EXCHANGE_NAME, logLevel, null, msg.getBytes(Charset.forName("UTF-8")));
            channel.basicPublish(EXCHANGE_NAME, logLevel, true, null, msg.getBytes(Charset.forName("UTF-8")));
        }
        Thread.sleep(2000);
        channel.close();
        connection.close();
    }
}

在這裏插入圖片描述




上述我們使用接受失敗確認消息採用了監聽器的方式,再RabbitMQ中還提供了其他的一些監聽器,如下:

信道關閉時觸發

channel.addShutdownListener(new ShutdownListener() {
    @Override
    public void shutdownCompleted(ShutdownSignalException cause) {
        System.out.println(cause.getMessage());
    }
});

連接關閉時觸發

connection.addShutdownListener(new ShutdownListener() {
    @Override
    public void shutdownCompleted(ShutdownSignalException cause) {
        System.out.println(cause.getMessage());
    }
});
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章