[RabbitMQ] RabbitMQ learning tutorial Topic mode Topic

Posted by misteraven on Wed, 15 Dec 2021 04:14:31 +0100

Theme mode

The routing rules of direct switches are exactly matching BindingKey and RoutingKey, but this strict matching method can not meet the needs of actual services in many cases.

topic switches extend the matching rules. Similar to direct switches, they also route messages to queues matching BindingKey and RoutingKey. However, the matching rules here are somewhat different. They agree:

  1. RoutingKey is a dot "." Split string (punctuated by "." Each separated string becomes a word). For example: com rabbitmq. client,java.util.concurrent
  2. BindingKey, like routingkey, is also a dot "." Split string
  3. There can be two special strings "*" and "#" in BindingKey for fuzzy matching. Where, * is used to match one word and # is used to match multiple words (which can be zero).

Examples of fuzzy matching:

  1. com.#: Can match: com zzc. java,com.zzc et al
  2. com.*: Can match: com zzc,com.java, etc

The Topic model is shown in the following figure:

Give an example of the above figure:

  1. The routing key is com rabbitmq. Client messages will be routed to Q1, Q2 and Q3 at the same time
  2. The routing key is com hidden. Client messages will be routed to Q2 and Q3
  3. The routing key is com hidden. Demo messages are routed to Q3
  4. The routing key is Java util. The concurrent message is discarded or returned to the producer because it does not match any routing keys

Background page management

Topic is further filtered on the direct mode

Create 3 new queues: topic_queue1,topic_queue2,topic_queue3


Create a new switch topic_exchange

Bind the relationship between switch and queue (binding keys need to be added. # represents 0 or more; * represents one)

Send messages in the switch (routing key needs to be specified)

Only queues with matching routing and binding keys receive messages

code implementation

producer
Different from routing mode:

  1. The routing key RoutingKey consists of multiple words
public class Producer {

    private static final String TOPIC_EXCHANGE_NAME = "code_topic_exchange";

    public static void main(String[] args) throws Exception{
        // 1. Get connection
        Connection connection = RabbitMqUtil.getConnection("producer");

        // 2. Obtain Channel through connection
        Channel channel = connection.createChannel();
        // 3. Declare the switch through the channel and the switch type is direct
        /**
         * @param1: Switch name
         * @param2: Switch Type 
         */
        channel.exchangeDeclare(TOPIC_EXCHANGE_NAME, BuiltinExchangeType.TOPIC);

        // 4. Message content
        String message = "Hello RabbitMQ Topic!!";
        String routingKey = "com.rabbitmq.client";
        // 5. Send a message to the switch and specify the routing key RoutingKey as com rabbitmq. client
        channel.basicPublish(TOPIC_EXCHANGE_NAME, routingKey, null, message.getBytes());
        System.out.println("Message sending completed~~~The message sent is:" + message);
        // 6. Close channels and connections
        RabbitMqUtil.close(connection, channel);
    }
}

consumer
Different from routing mode:

  1. The binding key has a fuzzy match in the BindingKey
public class Consumer {

    private static final String TOPIC_QUEUE_NAME = "topic_queue1";
    private static final String TOPIC_EXCHANGE_NAME = "code_topic_exchange";

    public static void main(String[] args) throws Exception{
        // Get connection
        Connection connection = RabbitMqUtil.getConnection("consumer");
        // Get channel
        Channel channel = connection.createChannel();
        String bindingKey = "*.rabbitmq.*";
        // Bind the queue to the switch and specify a binding key BindingKey
        channel.queueBind(TOPIC_QUEUE_NAME, TOPIC_EXCHANGE_NAME, bindingKey);

        // Define consumer
        com.rabbitmq.client.Consumer consumer = new DefaultConsumer(channel) {
            @Override
            public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
                // Body message body
                String msg = new String(body,"utf-8");
                System.out.println("Message received:" + msg);
            }
        };

        // listen queue 
        channel.basicConsume(TOPIC_QUEUE_NAME, true, consumer);

        System.out.println("Start receiving messages~~~");
        System.in.read();
        // Close channel and connection
        RabbitMqUtil.close(connection, channel);
    }
}
public class Consumer2 {

    private static final String TOPIC_QUEUE_NAME = "topic_queue2";
    private static final String TOPIC_EXCHANGE_NAME = "code_topic_exchange";

    public static void main(String[] args) throws Exception{
        // Get connection
        Connection connection = RabbitMqUtil.getConnection("consumer");
        // Get channel
        Channel channel = connection.createChannel();
        String bindingKey = "*.*.client";
        // Bind the queue to the switch and specify a binding key BindingKey
        channel.queueBind(TOPIC_QUEUE_NAME, TOPIC_EXCHANGE_NAME, bindingKey);

        // Define consumer
        com.rabbitmq.client.Consumer consumer = new DefaultConsumer(channel) {
            @Override
            public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
                // Body message body
                String msg = new String(body,"utf-8");
                System.out.println("Message received:" + msg);
            }
        };

        // listen queue 
        channel.basicConsume(TOPIC_QUEUE_NAME, true, consumer);

        System.out.println("Start receiving messages~~~");
        System.in.read();
        // Close channel and connection
        RabbitMqUtil.close(connection, channel);
    }
}

Topics: Java RabbitMQ Middleware