RabbitMQ文檔翻譯四(JAVA).路由

上一個教程中,我們構建了一個簡單的日誌記錄系統。我們可以向許多接收器廣播日誌信息。

在本教程中,我們將向它添加一個特性-我們將使它能夠只訂閱消息的一個子集。例如,我們將只能將關鍵錯誤消息定向到日誌文件(以節省磁盤空間),同時仍然能夠在控制檯上打印所有日誌消息。

綁定

在前面的示例中,我們已經創建了綁定。您可以回憶如下代碼:

channel.queueBind(queueName, EXCHANGE_NAME, "");

綁定是交換機和隊列之間的關係。這可以簡單地理解爲:隊列對來自此交換的消息感興趣。

綁定可以使用額外的routingKey參數。爲了避免與basic_publish參數混淆,我們將其稱爲綁定鍵binding key。這就是我們如何使用key創建綁定:

channel.queueBind(queueName, EXCHANGE_NAME, "black");

binding key 的含義取決於交換機類型。我們以前使用的扇形交換機交換完全忽略了它的值。

直連交換機

我們上一個教程中的日誌系統將所有消息廣播給所有用戶。我們希望擴展這一點,允許根據消息的嚴重性過濾消息。例如,我們可能希望將日誌消息寫入磁盤的程序只接收嚴重錯誤,而不會在警告或info日誌消息上浪費磁盤空間。

我們使用扇形交換機,這沒有給我們太多的靈活性-它只能進行無意識的廣播。

我們將改用直連交換機。直連交換機背後的路由算法很簡單——消息被髮送到binding key與消息路由key完全匹配的隊列。

爲了說明這一點,請考慮以下設置:
在這裏插入圖片描述
在這個設置中,我們可以看到直接交換X與兩個隊列綁定在一起。第一個隊列使用binding key(綁定密鑰)orange綁定,第二個隊列有兩個綁定,一個綁定密鑰爲black,另一個 綁定密鑰爲green。

在這種設置中,使用routing key(路由密鑰)orange發佈到交換機的消息將被路由到隊列Q1。路由鍵爲black或green的郵件將轉到Q2。所有其他消息都將被丟棄。

多個綁定

在這裏插入圖片描述
用同一個綁定鍵綁定多個隊列是完全合法的。在我們的例子中,我們可以在X和Q1之間添加一個綁定,綁定鍵爲black。在這種情況下,直接交換將表現爲扇形交換機的功能,並將消息廣播到所有匹配的隊列。路由key爲black的消息將同時傳送到Q1和Q2。

發送消息

我們將在日誌系統中使用此模型。代替扇形交換機我們將消息發送到直連交換機。我們將提供日誌級別作爲路由key。這樣接收程序就可以選擇它想要接收的級別。讓我們首先關注發送日誌消息。
一如既往,我們需要首先創建一個交換:

channel.exchangeDeclare(EXCHANGE_NAME, "direct");

我們已經準備好了發出一個信息:

channel.basicPublish(EXCHANGE_NAME, severity, null, message.getBytes());

爲了簡化問題,我們假設“級別”可以是 ‘info’, ‘warning’, 'error’之一。

訂閱

接收消息的工作方式與上一個教程中相同,但有一個例外——我們將爲我們感興趣的每個級別創建一個新的綁定。

String queueName = channel.queueDeclare().getQueue();
for(String severity : argv){
  channel.queueBind(queueName, EXCHANGE_NAME, severity);
}

把它們放在一起

在這裏插入圖片描述
代碼EmitLogDirect.java

import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;

public class EmitLogDirect {

  private static final String EXCHANGE_NAME = "direct_logs";

  public static void main(String[] argv) throws Exception {
    ConnectionFactory factory = new ConnectionFactory();
    factory.setHost("localhost");
    try (Connection connection = factory.newConnection();
         Channel channel = connection.createChannel()) {
        channel.exchangeDeclare(EXCHANGE_NAME, "direct");

        String severity = getSeverity(argv);
        String message = getMessage(argv);

        channel.basicPublish(EXCHANGE_NAME, severity, null, message.getBytes("UTF-8"));
        System.out.println(" [x] Sent '" + severity + "':'" + message + "'");
    }
  }
  //..
}

代碼ReceiveLogsDirect.java

import com.rabbitmq.client.*;

public class ReceiveLogsDirect {

  private static final String EXCHANGE_NAME = "direct_logs";

  public static void main(String[] argv) throws Exception {
    ConnectionFactory factory = new ConnectionFactory();
    factory.setHost("localhost");
    Connection connection = factory.newConnection();
    Channel channel = connection.createChannel();

    channel.exchangeDeclare(EXCHANGE_NAME, "direct");
    String queueName = channel.queueDeclare().getQueue();

    if (argv.length < 1) {
        System.err.println("Usage: ReceiveLogsDirect [info] [warning] [error]");
        System.exit(1);
    }

    for (String severity : argv) {
        channel.queueBind(queueName, EXCHANGE_NAME, severity);
    }
    System.out.println(" [*] Waiting for messages. To exit press CTRL+C");

    DeliverCallback deliverCallback = (consumerTag, delivery) -> {
        String message = new String(delivery.getBody(), "UTF-8");
        System.out.println(" [x] Received '" +
            delivery.getEnvelope().getRoutingKey() + "':'" + message + "'");
    };
    channel.basicConsume(queueName, true, deliverCallback, consumerTag -> { });
  }
}

照常編譯(請參閱教程1瞭解編譯和類路徑建議)。爲了方便起見,在運行示例時,我們將使用環境變量$CP(在Windows上爲%CP%)作爲classpath。

javac -cp $CP ReceiveLogsDirect.java EmitLogDirect.java

如果只想將“警告”和“錯誤”(而不是“信息”)日誌消息保存到文件中,只需打開控制檯並鍵入:

java -cp $CP ReceiveLogsDirect warning error > logs_from_rabbit.log

如果您想查看屏幕上的所有日誌消息,請打開一個新的終端並執行以下操作:

java -cp $CP ReceiveLogsDirect info warning error
# => [*] Waiting for logs. To exit press CTRL+C

要發出錯誤日誌消息,只需鍵入:

java -cp $CP EmitLogDirect error "Run. Run. Or it will explode."
# => [x] Sent 'error':'Run. Run. Or it will explode.'

繼續學習教程5,瞭解如何根據模式(pattern)監聽消息。

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