Routing 路由选择
前面的文章 介绍了,怎么广播消息到多个接收者,这一篇将怎么订阅消息的子集。
比如指定一个消费者只把 错误日志写入磁盘,另一个消费者仍然能够将所有的日志消息打印到屏幕上。
Binding
一个Binding描述的是交换机和队列之间的关系,比如描述 某个队列对这个交换机中的哪些消息感兴趣。
channel.queueBind(queueName, EXCHANGE_NAME, "");
第三个参数就是Binding的描述参数,也叫binding key(与basic_publish区分)。
创建一个简单的Binding,如下:
channel.queueBind(queueName, EXCHANGE_NAME, "black");
Binding key的指定和 交换机(exchange)的类型有关。
fanout不能提供太大的灵活性,所以为了筛选信息,我们使用direct交换机。
生产方:
生产方不能创建队列,发布时原本填队列名的位置填写 routkey
try(Connection connection=getConnection("guest","guest","localhost",5672,"/");
Channel channel=connection.createChannel()) {
channel.exchangeDeclare(args[0],"direct");
String message=getMessage(new String[]{"a","b","c"});
int i=0;
while (true){
Thread.sleep(1000);
channel.basicPublish(args[0],args[1], null,(i+++message).getBytes("utf-8"));
}
// Thread.sleep(2000);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
消费方:
主要是注意绑定routkey
public static void main(String[] args) {
try(Connection connection=BaseTest2.getConnection("guest","guest","localhost",5672,"/");
Channel channel=connection.createChannel()) {
channel.exchangeDeclare(args[0],"direct");
// channel.queueDeclare("red",false,false,false,null);
String queueName= channel.queueDeclare().getQueue();
channel.queueBind(queueName,args[0],args[1]);
// System.out.println(queueName);
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");
try {
doWork(message);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
System.out.println(message+" [x] Done");
}
// channel.basicAck(envelope.getDeliveryTag(),false);
}
};
channel.basicConsume(queueName,true, consumer);
Thread.sleep(200000);
} catch (Exception e) {
throw new RuntimeException(e);
}
}