一般情况下,我们不希望所有订阅的队列都消费,在某些场景下,我们希望不同的消息被不同的队列消费。这时候就要用到Direct类型的Exchange
绑定
在上一个示例中,我们在创建绑定的时候没有使用routingKey
:channel.queueBind(queueName,EXCHANGE_NAME,“”);
创建带有键的绑定方法:
channel.queueBind(queueName,EXCHANGE_NAME,“ black”);
场景模拟:
我们可能希望将日志消息写入磁盘的程序仅接收严重错误,而不会在将空间用在警告或信息日志消息上浪费磁盘空间。
- 分析:
使用扇出交换
,它并没有给我们带来太大的灵活性-它只能进行无意识的广播
我们将使用直接交换
。
直接交换背后的路由算法很简单-消息进入其绑定密钥与消息的路由密钥完全匹配的队列 。
`在此设置中,我们可以看到绑定了两个队列的直接交换X。第一个队列由绑定键orange绑定,第二个队列有两个绑定,一个绑定键为black,另一个绑定为green。
在这样的设置中,将使用路由键orange将要发布到交换机的消息 路由到队列Q1。路由键为black 或green的消息将转到Q2。所有其他消息将被丢弃。`
Provider
package com.op.routing.direct;
import com.op.util.RabbitMQUtils;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import java.io.IOException;
public class Provider {
public static void main(String[] args) throws IOException {
//获取连接对象
Connection connection = RabbitMQUtils.getConnection();
//获取连接通道对象
Channel channel = connection.createChannel();
//声明交换机 参数1:交换机名称 参数2:交换机类型 基于指令的Routing key转发
channel.exchangeDeclare("logs_direct","direct");
String key = "info";
//发布消息
channel.basicPublish("logs_direct",key,null,("指定的route key "+key+"的消息").getBytes());
//关闭资源
RabbitMQUtils.closeConnectionAndChanel(channel,connection);
}
}
Consumer1
package com.op.routing.direct;
import com.op.util.RabbitMQUtils;
import com.rabbitmq.client.*;
import java.io.IOException;
public class Consumer1 {
public static void main(String[] args) throws IOException {
Connection connection = RabbitMQUtils.getConnection();
Channel channel = connection.createChannel();
//声明交换机
channel.exchangeDeclare("logs_direct","direct");
//创建临时队列
String queue = channel.queueDeclare().getQueue();
//绑定队列和交换机
channel.queueBind(queue,"logs_direct","error");
channel.queueBind(queue,"logs_direct","info");
channel.queueBind(queue,"logs_direct","warn");
//消费消息
channel.basicConsume(queue,true,new DefaultConsumer(channel){
@Override
public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
System.out.println("消费者1: "+new String(body));
}
});
}
}
Consumer2
package com.op.routing.direct;
import com.op.util.RabbitMQUtils;
import com.rabbitmq.client.*;
import java.io.IOException;
public class Consumer2 {
public static void main(String[] args) throws IOException {
Connection connection = RabbitMQUtils.getConnection();
Channel channel = connection.createChannel();
//声明交换机
channel.exchangeDeclare("logs_direct","direct");
//创建临时队列
String queue = channel.queueDeclare().getQueue();
//绑定队列和交换机
channel.queueBind(queue,"logs_direct","error");
//消费消息
channel.basicConsume(queue,true,new DefaultConsumer(channel){
@Override
public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
System.out.println("消费者2: "+new String(body));
}
});
}
}