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);
}
}