RabbitMQ learning-the fifth routing

In the last article we built a simple log system, we can broadcast log messages to multiple recipients.

In this article we will add a feature to receive only part of the message in the future. For example, I only save some error logs to a file, and print all logs to the console.

1. Bindings

In the previous article, we have created a binding, the code is as follows:

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

A binding is a relationship between exchange and Queue. It can be simply understood as: this Queue is interested in the exchange messages relative to it (the original text is the queue is interested in messages from this exchange).

Binding can use an existing routingKey parameter. In order to avoid confusion with the basic_publish parameter, we call it the binding key. The following is how we use the key to create a binding:

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

The meaning of the binding key sometimes depends on the type of exchange. For exchanges of type Fanout, the binding key is ignored.

2. Direct exchange

The log system in the previous article will broadcast all log messages to all consumers. We want to expand to filter log messages based on their log level. For example: we only want to write the log of error level to the disk file, while the log messages of other levels are filtered out.

We used the fanout type exchange before, but this way there won't be much flexibility.

Here we are going to use the direct type of exchange. The routing algorithm of Direct type exchange is very simple: if a message can reach this queue, the binding key and routing key need to match exactly.

To illustrate this truth, you can look at the description below:

In such a structure, we can see the exchange X of the direct type, and there are two queues bound to it. The first queue is bound to exchange X with orange as the binding key, and the second queue is bound to exchange X with two binding keys (black and green).

In such settings, a message is pushed to the exchange, if the routing key used is orange, the message will be routed to Q1; if the routing key used is black or green, then the message will be routed to Q2 in. All other messages will be discarded.

3. Multiple bindings

It is also possible to use the same binding to bind multiple queues to the same exchange. For example, on the basis of the previous example, add the binding key name black between X and Q1. In this case, the direct type exchange here is the same as the fanout type, and the message can be pushed to all queues. Messages with routing key black will be pushed to Q1 and Q2.

4. Sending logs (Emitting logs)

We will use this model, instead of using the fanout type of exchange, but the direct type. We use the log level as the routing key, and the receiving end receives the message according to the set log level as the binding key. First look at the launch log:

As before, first create an exchange:

channel.exchangeDeclare (EXCHANGE_NAME, "direct");
Then prepare to send a message;

channel.basicPublish (EXCHANGE_NAME, severity, null, message.getBytes ());
"severity" here can be "info", "warning", "error", etc.

5. Subscription (Subscribing)

The messages received here are the same as in the previous blog post, with one exception: we will bind each log level of interest.

String queueName = channel.queueDeclare().getQueue();

for(String severity : argv){
channel.queueBind(queueName, EXCHANGE_NAME, severity);
}
6、最终实现

EmitLogDirect.java的代码:
复制代码
public class EmitLogDirect {
private static final String EXCHANGE_NAME = “direct_logs”;
public static void main(String[] argv)
throws java.io.IOException {
ConnectionFactory factory = new ConnectionFactory();
factory.setHost(“localhost”);
Connection connection = factory.newConnection();
Channel channel = connection.createChannel();

    //声明direct类型的exchange
    channel.exchangeDeclare(EXCHANGE_NAME, "direct");

// Get the log level
String severity = getSeverity (argv);

    //拿到日志消息
    String message = getMessage(argv);

    //指定routing key,发送消息
    channel.basicPublish(EXCHANGE_NAME, severity, null, message.getBytes());
    System.out.println(" [x] Sent '" + severity + "':'" + message + "'");

    channel.close();
    connection.close();
}
//..

}
复制代码
ReceiveLogsDirect.java的代码:
复制代码
public class ReceiveLogsDirect {
private static final String EXCHANGE_NAME = “direct_logs”;
public static void main(String[] argv)
throws java.io.IOException,
java.lang.InterruptedException {
ConnectionFactory factory = new ConnectionFactory();
factory.setHost(“localhost”);
Connection connection = factory.newConnection();
Channel channel = connection.createChannel();

    //声明direct类型的exchange
    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");

    QueueingConsumer consumer = new QueueingConsumer(channel);
    channel.basicConsume(queueName, true, consumer);

    while (true) {
        QueueingConsumer.Delivery delivery = consumer.nextDelivery();
        String message = new String(delivery.getBody());
        String routingKey = delivery.getEnvelope().getRoutingKey();

        System.out.println(" [x] Received '" + routingKey + "':'" + message + "'");
    }
}

}
Copy code
Run three log receivers:
receive error and info level logs:

Receive error level logs:

Receive info level logs:

Run two log generators:
generate error level logs:

Generate info level logs:

Observe the changes on the receiver side:
Receive error level receivers and only receive error level logs:

Receive info level receivers, only receive info level logs:

Receivers for both error and info level logs, and info and error level logs:

7. Summary:

To remember the routing key on the producer side, then set the binding key on the consumer side as the previous routing key, you can use the direct type of exchange to get the information you need.

Published 40 original articles · 25 praises · 100,000+ views

Guess you like

Origin blog.csdn.net/yym373872996/article/details/105651955