RabbitMQ --- 路由Routing

結合上一篇文章接着往下寫。

路由 routing

日誌系統,將error的日誌信息發送到一個隊列,進行保存到logs文件中。將error info warning的日誌信息發送到另一個隊列,進行控制檯打印操作。這裏可是通過 綁定祕鑰 路由祕鑰參數來配置。

再上一個技術發佈訂閱,添加一點限制,是消費者只能訂閱一部分消息。

例如,我們只能將關鍵錯誤消息定向到日誌文件,同時仍然能夠在控制檯上打印所有日誌消息

綁定可以採用routingKey參數,爲了避免與basic_Publish 參數混淆,將其稱之爲綁定祕鑰
channel.queueBind(queueName, exchangeName, "severityError");
綁定祕鑰的含義取決於交換機的類型,上一篇中使用的fanout類型交換機忽略了綁定祕鑰。

直接交換機 direct

Exchange fanout(扇出交換機),它沒有給我們太大靈活性,它只能進行無意識的廣播。
Exchange direct(直接交換機),直接交換背後的路由算法很簡單,消息進入隊列,其綁定祕鑰和路由祕鑰完全匹配(匹配不上的消息被丟棄)

多個綁定

使用相同的綁定祕鑰綁定多個隊列是完全合法的。

在這裏插入圖片描述

貼代碼

生產者代碼
public class Routingsend {
    final static String EXCHANGE_NAME = "direct_logs";
    static ConnectionUtil connUtil = new ConnectionUtil();
    public static void main(String[] args) throws Exception {
        Connection conn = connUtil.getConn();
        Channel channel = conn.createChannel();
        //聲明交換機 指定direct直連類型
        channel.exchangeDeclare(EXCHANGE_NAME, "direct");
        String message = "Exchange type direct, test routing";
        //定義路由祕鑰 error
        String severity = "error";
        //發佈到交換機
        channel.basicPublish(EXCHANGE_NAME, severity, null, message.getBytes());
        System.out.println("綁定祕鑰:"+severity+", 消息:"+message);
		//定義路由祕鑰 info
        String severity2 = "info";
        //發佈到交換機
        channel.basicPublish(EXCHANGE_NAME, severity2, null, message.getBytes());
        System.out.println("綁定祕鑰:"+severity2+", 消息:"+message);
		//定義路由祕鑰 warning
        String severity3 = "warning";
        //發佈到交換機
        channel.basicPublish(EXCHANGE_NAME, severity3, null, message.getBytes());
        System.out.println("綁定祕鑰:"+severity3+", 消息:"+message);
        // 關閉通道和連接
        channel.close();
        conn.close();

    }

}

消費者1 代碼,用來將error的日誌信息發送到一個隊列,進行保存到logs文件中
public class RoutingReceiver1 {
    final static String EXCHANG_NAME = "direct_logs";
    static ConnectionUtil connUtil = new ConnectionUtil();
    public static void main(String[] args)  throws Exception {
        Connection conn = connUtil.getConn();
        Channel channel = conn.createChannel();
        //聲明交換機 指定direct直連類型
        channel.exchangeDeclare(EXCHANG_NAME, "direct");
        //獲取臨時隊列名稱
        String queneName = channel.queueDeclare().getQueue();
        //綁定隊列 error爲綁定祕鑰,其綁定祕鑰和路由祕鑰完全匹
        channel.queueBind(queneName, EXCHANG_NAME, "error");
        DeliverCallback deliverCallback = (consumerTag, delivery) -> {
            String message = new String(delivery.getBody(), "UTF-8");
            System.out.println("路由祕鑰:"+delivery.getEnvelope().getRoutingKey()+",接受消息: '" + message + "'");
        };
        channel.basicConsume(queneName, true, deliverCallback, consumerTag -> {});
    }
}

消費者2 代碼,將error info warning的日誌信息發送到另一個隊列,進行控制檯打印操作
public class RoutingReceiver2 {
    final static String EXCHANG_NAME = "direct_logs";
    static ConnectionUtil connUtil = new ConnectionUtil();
    public static void main(String[] args)  throws Exception {
        Connection conn = connUtil.getConn();
        Channel channel = conn.createChannel();
        //聲明交換機 指定direct直連類型
        channel.exchangeDeclare(EXCHANG_NAME, "direct");
        //獲取臨時隊列名稱
        String queneName = channel.queueDeclare().getQueue();
        //綁定隊列 綁定多個
        channel.queueBind(queneName, EXCHANG_NAME, "info");
        //使用相同的綁定祕鑰綁定多個隊列是完全合法的,上面也用這個綁定祕鑰
        channel.queueBind(queneName, EXCHANG_NAME, "error");
        channel.queueBind(queneName, EXCHANG_NAME, "warning");
        DeliverCallback deliverCallback = (consumerTag, delivery) -> {
            String message = new String(delivery.getBody(), "UTF-8");
            System.out.println("路由祕鑰:"+delivery.getEnvelope().getRoutingKey()+",接受消息: '" + message + "'");
        };
        channel.basicConsume(queneName, true, deliverCallback, consumerTag -> {});
    }
}

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