RabbitMQ官網(wǎng)中文版教程:
http://rabbitmq.mr-ping.com/tutorials_with_python/[4]Routing.html
上述教程示例為pathon版,Java版及相應解釋如下:
生產(chǎn)者
package com.xc.rabbit.routing;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
/**
* Created by xc.
*/
public class RoutingSendDirect {
private static final String EXCHANGE_NAME = "direct_logs";
// 路由關(guān)鍵字
private static final String[] routingKeys = new String[] {"info", "warning", "error"};
public static void main(String[] args) throws Exception {
ConnectionFactory factory = new ConnectionFactory();
factory.setHost("localhost");
factory.setPort(5672);
factory.setUsername("rabbit");
factory.setPassword("carrot");
// 創(chuàng)建一個新的連接
Connection connection = factory.newConnection();
// 創(chuàng)建一個頻道
Channel channel = connection.createChannel();
// 聲明交換器
channel.exchangeDeclare(EXCHANGE_NAME, "direct");
// 發(fā)送消息
for (String severity : routingKeys) {
String message = "Send the message level : " + severity;
channel.basicPublish(EXCHANGE_NAME, severity, null, message.getBytes());
System.out.println(" [x] Sent '" + severity + "':'" + message + "'");
}
channel.close();
connection.close();
}
}
消費者1
package com.xc.rabbitmq.routing;
import com.rabbit.client.*;
import java.io.IOException;
/**
* Created by xc.
*/
public class ReceiveLogsDirect1 {
// 交換器名稱
private static final String EXCHANGE_NAME = "direct_logs";
// 路由關(guān)鍵字
private static final String[] routingKey = new String[]{"info", "warning", "error"};
public static void main(String[] args) throws Exception {
ConnectionFactory factory = new ConnectionFactory();
factory.setHost("localhost");
factory.setPort(5672);
factory.setUsername("rabbit");
factory.setPassword("carrot");
// 創(chuàng)建一個新的連接
Connection connection = factory.newConnection();
// 創(chuàng)建一個頻道
Channel channel = connection.createChannel();
// 聲明交換器
channel.exchangeDeclare(EXCHANGE_NAME, "direct");
// 獲取匿名隊列名稱
String queueName = channel.queueDeclare().getQueue();
// 根據(jù)路由關(guān)鍵字進行多重綁定
for (String severity : routingKey) {
channel.queueBind(queueName, EXCHANGE_NAME, severity);
System.out.println("ReceiveLogsDirect1 exchange : " + EXCHANGE_NAME +
", queue : " + queueName + ", BindRoutingKey : " + severity);
}
System.out.println("ReceiveLogsDirect1 [*] Waiting for messages. To exit press CTRL + C");
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(" [x] Received '" + envelope.getRoutingKey() + "':'" + message + "'");
}
};
channel.basicConsume(queueName, true, consumer);
}
}
消費者2
package com.xc.rabbit.routing;
import com.rabbitmq.client.*;
import java.io.IOException;
/**
* Created by xc.
*/
public class ReceiveLogsDirect2 {
// 交換器名稱
private static final String EXCHANGE_NAME = "direct_logs";
// 路由關(guān)鍵字
private static final String[] routingKey = new String[]{"error"};
public static void main(String[] args) throws Exception {
ConnectionFactory factory = new ConnectionFactory();
factory.setHost("localhost");
factory.setPort(5672);
factory.setUsername("rabbit");
factory.setPassword("carrot");
// 創(chuàng)建一個新的連接
Connection connection = factory.newConnection();
// 創(chuàng)建一個頻道
Channel channel = connection.createChannel();
// 聲明交換器
channel.exchangeDeclare(EXCHANGE_NAME, "direct");
// 獲取匿名隊列名稱
String queueName = channel.queueDeclare().getQueue();
// 根據(jù)路由關(guān)鍵字進行多重綁定
for (String severity : routingKey) {
channel.queueBind(queueName, EXCHANGE_NAME, severity);
System.out.println("ReceiveLogsDirect2 exchange : " + EXCHANGE_NAME +
", queue : " + queueName + ", BindRoutingKey : " + severity);
}
System.out.println("ReceiveLogsDirect2 [*] Waiting for messages. To exit press CTRL + C");
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(" [x] Received '" + envelope.getRoutingKey() + "':'" + message + "'");
}
};
channel.basicConsume(queueName, true, consumer);
}
}
運行結(jié)果如下:
由圖可知,生產(chǎn)者發(fā)出的消息,根據(jù)不同的路由,發(fā)送到不同的隊列,進而被不同的消費者接收。
先跑消費者程序,在跑生產(chǎn)者程序。否則,生產(chǎn)者的消息到達交換器之后,如果沒有隊列連上交換器, 則消息被直接丟棄。
注意:
Bindings can take an extra routingKey parameter. To avoid the confusion with a basic_publish,parameter we're going to call it a binding key.
binding key和routing key是一回事,為了避免概念重復,channel.queueBind時叫binding key, channel.basicPublish時叫routing key。The routing algorithm behind a direct exchange is simple - a message goes to the queues whose binding key exactly matches the routing key of the message.
direct交換器的路由規(guī)則很簡單,消息會路由到binding key與routing key相同的隊列。