RabbitMQ Introduction-Topic Mode

Keywords: RabbitMQ

In the previous article, "RabbitMQ Introduction - Routing Direct Connection Mode", we introduced the ability to send messages directionally and according to custom rules. It seems that this Routing mode is already flexible, but that's not enough. We have more flexible Topic modes.

Topic mode


image.png
  • There is no change in the composition of the model compared with the previous ones: a producer P, a switch X, multiple message queues Q, and multiple consumers C.

  • In Exchange, the rules used to dispatch messages to message queue Queue are different. We see symbols "*" and "#", which can be considered wildcards.

  • "*" is used to match a word, such as "a","abc", etc; "" is used to match 0 or more words, such as "",""abc","abc. def"and so on.

Sender

/**
 * Created by jackie on 17/8/7.
 */
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("192.168.3.161");
        Connection connection = factory.newConnection();
        Channel channel = connection.createChannel();

        channel.exchangeDeclare(EXCHANGE_NAME, BuiltinExchangeType.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 + "'");

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

    private static String getSeverity(String[] strings){
        if (strings.length < 1)
            return "info";
        return strings[0];
    }

    private static String getMessage(String[] strings){
        if (strings.length < 2)
            return "Hello World!";
        return joinStrings(strings, " ", 1);
    }

    private static String joinStrings(String[] strings, String delimiter, int startIndex) {
        int length = strings.length;
        if (length == 0 ) return "";
        if (length < startIndex ) return "";
        StringBuilder words = new StringBuilder(strings[startIndex]);
        for (int i = startIndex + 1; i < length; i++) {
            words.append(delimiter).append(strings[i]);
        }
        return words.toString();
    }
}
  • Channel. exchange Declare (EXCHANGE_NAME, BuiltinExchangeType. TOPIC); the Exchagne mode specified here is Topic mode

  • Through String routing Key = getRouting (argv); implement filling in routing key parameters in Program arguments

  • Through String message = getMessage(argv); implement filling in the message sent in Program arguments

At this point, we assign the following values to Program argument and start the sender program


image.png

After the program runs, you can see Exchange named topic_logs in RabbitMQ management application.

receiving end

/**
 * Created by jackie on 17/8/7.
 */
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("192.168.3.161");
        Connection connection = factory.newConnection();
        Channel channel = connection.createChannel();

        channel.exchangeDeclare(EXCHANGE_NAME, BuiltinExchangeType.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");

        Consumer consumer = new DefaultConsumer(channel) {
            @Override
            public void handleDelivery(String consumerTag, Envelope envelope,
                                       AMQP.BasicProperties properties, byte[] body) throws IOException {
                String message = new String(body, "UTF-8");
                System.out.println(" [x] Received '" + envelope.getRoutingKey() + "':'" + message + "'");
            }
        };
        channel.basicConsume(queueName, true, consumer);
    }
}
  • Similar to Routing mode, declare the same Exchange name as the sender

  • The input parameters of routing key obtained through Program arguments and bound to Exchange make it possible to use flexible wildcards.

Operation status

We will start two consumers and develop two sets of Routing key rules.
First consumer


image.png

Second consumer


image.png

When two consumers are started and a message is sent from the sender, we can see that both consumers send the message through the Routing key rule.



31ff000395b3dedc07a2

Note: In fact, if Routing key is written as "#" to indicate that it can accept all messages, it is similar to broadcast mode.
This is the Topic mode, so far, several major Rabbit MQ modes have been finished. Do you have a basic understanding of RabbitMQ?

If you think reading this article is helpful to you, please click the "like" button, your "like" will be my greatest writing motivation! If you want to keep an eye on my articles, please scan the two-dimensional code and pay attention to Jackie Zheng's Wechat Public Number. I will push my articles to you and share with you the high quality articles I have read everyday.


Posted by help_lucky on Thu, 06 Jun 2019 12:16:34 -0700