绑定
绑定是exchange和Queue之间的关系。这可以简单地理解为:Queue对来自此exchange的消息感兴趣。
绑定可以采用额外的routingKey参数。为了避免与basic_publish参数混淆,我们将其称为 绑定密钥。这就是我们如何使用键创建绑定。绑定密钥的含义取决于exchange类型.
channel.queueBind(queueName,EXCHANGE_NAME,“black”);
比如在一个日志系统中,一般是希望把出错误信息的日志存到磁盘里保存起来,而不希望把警告日志和普通信息日志也保存起来而浪费空间,所以这里就需要exchange的类型,而fanout是把消息广播给队列,不合适。
这里要用direct类型,direct背后的路由算法很简单 - 消息进入队列,其 绑定密钥与消息的路由密钥完全匹配。
在此设置中,我们可以看到direct与两个绑定到它的队列。第一个队列绑定orange绑定,第二个绑定有两个绑定,一个绑定密钥为black,另一个绑定为green。
在这样的设置中,使用路由密钥orange发布到交换机的消息 将被路由到队列Q1。路由键为black 或green的消息将转到Q2。所有其他消息将被丢弃。
多个绑定
使用相同的绑定密钥绑定多个队列是完全合法的,像上图这种情况相当于fanout类型,广播队列。
日志的订阅
---------------------------生产者---------------------------------
channel.exchangeDeclare(EXCHANGE_NAME,“direct”);
channel.basicPublish(EXCHANGE_NAME,severity,null,message.getBytes());
----------------------------消费者--------------------------------
String queueName = channel.queueDeclare()。getQueue();
for(String severity:argv){
channel.queueBind(queueName,EXCHANGE_NAME,severity);
}
生产者
import com.rabbitmq.client.*;
import java.io.IOException;
public class EmitLogDirect {
private static final String EXCHANGE_NAME = "direct_logs";
public static void main(String[] argv)
throws java.io.IOException {
ConnectionFactory factory = new ConnectionFactory();
factory.setHost("localhost");
Connection connection = factory.newConnection();
Channel channel = connection.createChannel();
channel.exchangeDeclare(EXCHANGE_NAME, "direct");
String severity = getSeverity(argv);
String message = getMessage(argv);
channel.basicPublish(EXCHANGE_NAME, severity, null, message.getBytes());
System.out.println(" [x] Sent '" + severity + "':'" + message + "'");
channel.close();
connection.close();
}
//..
}
消费者
import com.rabbitmq.client.*;
import java.io.IOException;
public class ReceiveLogsDirect {
private static final String EXCHANGE_NAME = "direct_logs";
public static void main(String[] argv) throws Exception {
ConnectionFactory factory = new ConnectionFactory();
factory.setHost("localhost");
Connection connection = factory.newConnection();
Channel channel = connection.createChannel();
channel.exchangeDeclare(EXCHANGE_NAME, "direct");
String queueName = channel.queueDeclare().getQueue();
if (argv.length < 1){
System.err.println("Usage: ReceiveLogsDirect [info] [warning] [error]");
System.exit(1);
}
for(String severity : argv){
channel.queueBind(queueName, EXCHANGE_NAME, severity);
}
System.out.println(" [*] 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);
}
}