Direct exchange
直接交换器模式,其路由算法非常简单,一条消息只发送到完全匹配的队列。
我们使用以下几个实例来说明:
实例1
在这个直接交换器实例中,我们绑定了两个队列到交换器中,第一个队列使用绑定键orange,第二个队列使用black和green绑定键。
在这个实例中,路由键为“orange”的消息将被分发到队列Q1,路由键为”black”和“green”将被发到队列Q2,其他的消息将被丢弃。
实例2
在这里实例,我们使用两个队列,同时两个队列都使用了相同的绑定键,那么路由键为“black”的消息将发送到两个队列里,有点像fanout模式。
实例3
该实例,队列1使用了error作为绑定键,则路由键为error的消息将发送到队列1,队列2,使用info、error、warning作为绑定键,那么路右键为info、error、warning都会发送到队列2。
具体看下代码:
生产者:
发送消息:
Send error:Hello,RabbitMq1
Send info:Hello,RabbitMq2
Send warning:Hello,RabbitMq3
package com.enjoy.testrabbitmq;
import com.enjoy.common.RabbitmqConnection;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import java.io.IOException;
import java.util.concurrent.TimeoutException;
/**
*类说明:direct类型交换器的生产者
*/
public class TestProducerDirect {
public final static String EXCHANGE_NAME = "direct_exchange";
public static void main(String[] args)
throws IOException, TimeoutException {
Connection connection = RabbitmqConnection.getConnection();
/*创建信道*/
Channel channel = connection.createChannel();
/*创建交换器*/
channel.exchangeDeclare(EXCHANGE_NAME,"direct");
/*日志消息级别,作为路由键使用*/
String[] routekeys = {"error","info","warning"};
for(int i=0;i<routekeys.length;i++){
String routekey = routekeys[i];
String msg = "Hello,RabbitMq"+(i+1);
/*发布消息,需要参数:交换器,路由键,其中以日志消息级别为路由键*/
channel.basicPublish(
EXCHANGE_NAME//交换器
,routekey//路由键
,null
,msg.getBytes());
System.out.println("Send "+routekey+":"+msg);
}
channel.close();
connection.close();
}
}
消费者1
接收消息:
Send error:Hello,RabbitMq1
Send info:Hello,RabbitMq2
Send warning:Hello,RabbitMq3
package com.enjoy.testrabbitmq;
import com.enjoy.common.RabbitmqConnection;
import com.rabbitmq.client.*;
import java.io.IOException;
import java.util.concurrent.TimeoutException;
/**
*类说明:普通的消费者
*/
public class TestConsumerDirect {
public static void main(String[] argv)
throws IOException, TimeoutException {
// 打开连接和创建频道,与发送端一样
Connection connection = RabbitmqConnection.getConnection();
final Channel channel = connection.createChannel();
channel.exchangeDeclare(TestProducerDirect.EXCHANGE_NAME,
"direct");
/*声明一个随机队列*/
String queueName = channel.queueDeclare().getQueue().substring(4);
System.out.println("queueName="+queueName);
channel.queueDeclare(queueName,false,false,
false,null);
/*队列绑定到交换器上时,是允许绑定多个路由键的,也就是多重绑定*/
String[] routekeys={"error","info","warning"};
for(String routekey:routekeys){
channel.queueBind(queueName,TestProducerDirect.EXCHANGE_NAME,
routekey);
}
System.out.println("waiting for message........");
/*声明了一个消费者*/
final Consumer consumer = new DefaultConsumer(channel){
@Override
public void handleDelivery(String consumerTag,
Envelope envelope,
AMQP.BasicProperties properties,
byte[] body) throws IOException {
String message = new String(body, "UTF-8");
System.out.println("Received["+envelope.getRoutingKey()
+"]"+message);
}
};
/*消费者正式开始在指定队列上消费消息*/
channel.basicConsume(queueName,true,consumer);
}
}
消费者2
接收消息:Received[error]Hello,RabbitMq1
package com.enjoy.testrabbitmq;
import com.enjoy.common.RabbitmqConnection;
import com.rabbitmq.client.*;
import java.io.IOException;
import java.util.concurrent.TimeoutException;
/**
*类说明:普通的消费者
*/
public class TestConsumerDirectError {
public static void main(String[] argv)
throws IOException, TimeoutException {
// 打开连接和创建频道,与发送端一样
Connection connection = RabbitmqConnection.getConnection();
final Channel channel = connection.createChannel();
channel.exchangeDeclare(TestProducerDirect.EXCHANGE_NAME,
"direct");
/*声明一个随机队列*/
String queueName = channel.queueDeclare().getQueue().substring(4);
System.out.println("queueName="+queueName);
channel.queueDeclare(queueName,false,false,
false,null);
/*队列绑定到交换器上的路由键*/
String routekey="error";
channel.queueBind(queueName,TestProducerDirect.EXCHANGE_NAME, routekey);
System.out.println("waiting for message........");
/*声明了一个消费者*/
final Consumer consumer = new DefaultConsumer(channel){
@Override
public void handleDelivery(String consumerTag,
Envelope envelope,
AMQP.BasicProperties properties,
byte[] body) throws IOException {
String message = new String(body, "UTF-8");
System.out.println("Received["+envelope.getRoutingKey()
+"]"+message);
}
};
/*消费者正式开始在指定队列上消费消息*/
channel.basicConsume(queueName,true,consumer);
}
}