转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/37706355
上一篇博客中,我们进步改良了我们的日志系统。我们使用direct类型转发器,使得接收者有能力进行选择性的接收日志,,而非fanout那样,只能够无脑的转发,如果你还不了解:RabbitMQ (四) 路由选择 (Routing)。
虽然使用direct类型改良了我们的系统,但是仍然存在一些局限性:它不能够基于多重条件进行路由选择。发送端EmitLogTopic.java:
package com.zhy.rabbit._05_topic_exchange; import java.util.UUID; import com.rabbitmq.client.Channel; import com.rabbitmq.client.Connection; import com.rabbitmq.client.ConnectionFactory; public class EmitLogTopic { private static final String EXCHANGE_NAME = "topic_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, "topic"); String[] routing_keys = new String[] { "kernal.info", "cron.warning", "auth.info", "kernel.critical" }; for (String routing_key : routing_keys) { String msg = UUID.randomUUID().toString(); channel.basicPublish(EXCHANGE_NAME, routing_key, null, msg .getBytes()); System.out.println(" [x] Sent routingKey = "+routing_key+" ,msg = " + msg + "."); } channel.close(); connection.close(); } }
接收端1,ReceiveLogsTopicForKernel.java
package com.zhy.rabbit._05_topic_exchange; import com.rabbitmq.client.Channel; import com.rabbitmq.client.Connection; import com.rabbitmq.client.ConnectionFactory; import com.rabbitmq.client.QueueingConsumer; public class ReceiveLogsTopicForKernel { private static final String EXCHANGE_NAME = "topic_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, "topic"); // 随机生成一个队列 String queueName = channel.queueDeclare().getQueue(); //接收所有与kernel相关的消息 channel.queueBind(queueName, EXCHANGE_NAME, "kernel.*"); System.out.println(" [*] Waiting for messages about kernel. 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 = " + routingKey + ",msg = " + message + "."); } } }
接收端2,ReceiveLogsTopicForCritical.java
package com.zhy.rabbit._05_topic_exchange; import com.rabbitmq.client.Channel; import com.rabbitmq.client.Connection; import com.rabbitmq.client.ConnectionFactory; import com.rabbitmq.client.QueueingConsumer; public class ReceiveLogsTopicForCritical { private static final String EXCHANGE_NAME = "topic_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, "topic"); // 随机生成一个队列 String queueName = channel.queueDeclare().getQueue(); // 接收所有与kernel相关的消息 channel.queueBind(queueName, EXCHANGE_NAME, "*.critical"); System.out .println(" [*] Waiting for critical 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 = " + routingKey + ",msg = " + message + "."); } } }
运行结果:
[x] Sent routingKey = kernal.info ,msg = a7261f0d-18cc-4c85-ba80-5ecd9283dae7.
[x] Sent routingKey = cron.warning ,msg = 0c7e4484-66e0-4846-a869-a7a266e16281.
[x] Sent routingKey = auth.info ,msg = 3273f21f-6e6e-42f2-83df-1f2fafa7a19a.
[x] Sent routingKey = kernel.critical ,msg = f65d3e1a-0619-4f85-8b0d-59375380ecc9.
--------------------------------------------------------------------------------------------------------------------
[*] Waiting for messages about kernel. To exit press CTRL+C
[x] Received routingKey = kernel.critical,msg = f65d3e1a-0619-4f85-8b0d-59375380ecc9.
--------------------------------------------------------------------------------------------------------------------
[*] Waiting for critical messages. To exit press CTRL+C
[x] Received routingKey = kernel.critical,msg = f65d3e1a-0619-4f85-8b0d-59375380ecc9.
可以看到,我们通过使用topic类型的转发器,成功实现了多重条件选择的订阅。