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:
- RoutingKey is a dot "." Split string (punctuated by "." Each separated string becomes a word). For example: com rabbitmq. client,java.util.concurrent
- BindingKey, like routingkey, is also a dot "." Split string
- 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:
- com.#: Can match: com zzc. java,com.zzc et al
- com.*: Can match: com zzc,com.java, etc
The Topic model is shown in the following figure:
Give an example of the above figure:
- The routing key is com rabbitmq. Client messages will be routed to Q1, Q2 and Q3 at the same time
- The routing key is com hidden. Client messages will be routed to Q2 and Q3
- The routing key is com hidden. Demo messages are routed to Q3
- 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:
- 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:
- 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); } }