Routing路由模式
-
队列与交换机的绑定,不是任意绑定,而是要指定一个RoutingKey
-
消息的发送方在向 Exchange发送消息时,也必须指定消息的RoutingKey
-
Exchange不再把消息交给每一个绑定的队列, 而是根据消息的Routing Key进行判断,只有队列的Routingkey与消息的Rbuting key完全一致,才会接收到消息
P: 生产者,向Exchange发送消息,发送消息时,会指定一个Routing key
X: Exchange (交换机),接收生产者的消息,然后把消息递交给与Routing key完全匹配的队列
C1: 消费者,其所在队列指定了需要Routing key为error的消息
C2: 消费者,其所在队列指定了需要Routing key为info、error、warning 的消息
代码实现
生产者:
public class Producer_Routing {
public static void main(String[] args) throws IOException, TimeoutException {
ConnectionFactory factory = new ConnectionFactory();
factory.setHost("192.168.1.3");
factory.setPort(5672);
factory.setVirtualHost("/sx");
factory.setUsername("sx");
factory.setPassword("123456");
Connection connection = factory.newConnection();
Channel channel = connection.createChannel();
String exchangeName = "test_direct";
channel.exchangeDeclare(exchangeName, BuiltinExchangeType.DIRECT, true, false, false, null);
//创建队列 2个
String queue1 = "test_direct_queue1";
String queue2 = "test_direct_queue2";
channel.queueDeclare(queue1, true, false, false, null);
channel.queueDeclare(queue2, true, false, false, null);
//绑定队列和交换机
channel.queueBind(queue1, exchangeName, "error");
channel.queueBind(queue2, exchangeName, "info");
channel.queueBind(queue2, exchangeName, "error");
channel.queueBind(queue2, exchangeName, "warning");
String body = "log";
//发送消息
//第一次
//channel.basicPublish(exchangeName, "info", null, body.getBytes());
//第二次
channel.basicPublish(exchangeName, "error", null, body.getBytes());
//释放资源
channel.close();
connection.close();
}
}
消费者C1 只能收到Routing key为error的消息,并进行处理
package com.sx.consumer;
import com.rabbitmq.client.*;
import java.io.IOException;
import java.util.concurrent.TimeoutException;
public class Consumer_RoutingC1 {
public static void main(String[] args) throws IOException, TimeoutException {
ConnectionFactory factory = new ConnectionFactory();
factory.setHost("192.168.1.3");
factory.setPort(5672);
factory.setVirtualHost("/sx");
factory.setUsername("sx");
factory.setPassword("123456");
Connection connection = factory.newConnection();
Channel channel = connection.createChannel();
Consumer consumer = new DefaultConsumer(channel) {
@Override
public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
System.out.println("body = " + new String(body));
System.out.println("重大错误,错误信息已保存到数据库中!");
}
};
channel.basicConsume("test_direct_queue1", true, consumer);
}
}
消费者C2 可以收到Routing key为error、warning、info的消息,将信息打印到控制台
package com.sx.consumer;
import com.rabbitmq.client.*;
import java.io.IOException;
import java.util.concurrent.TimeoutException;
public class Consumer_RoutingC2 {
public static void main(String[] args) throws IOException, TimeoutException {
ConnectionFactory factory = new ConnectionFactory();
factory.setHost("192.168.1.3");
factory.setPort(5672);
factory.setVirtualHost("/sx");
factory.setUsername("sx");
factory.setPassword("123456");
Connection connection = factory.newConnection();
Channel channel = connection.createChannel();
Consumer consumer = new DefaultConsumer(channel) {
@Override
public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
System.out.println("body = " + new String(body));
System.out.println("打印日志到控制台");
}
};
channel.basicConsume("test_direct_queue2", true, consumer);
}
}
运行结果
第一次运行,Routing Key为info
第二次运行,Routing key为error