您的位置:首页 > 其它

RabbitMQ学习之四:发布/订阅(direct方式)

2015-12-18 14:06 501 查看
参考/article/1580297.html和RabbitMQ官网,加之自己部分修改和实验,因是新手自学,难免有不对之处,欢迎大家指正,小弟先谢过了.

这篇文章主要学习下exchange类型的第二种类型:direct

上一篇文章中,主要学习了RabbitMQ exchange的fanout(广播方式),即producer发送的消息会被所有的消费者接收处理,有木有”强买强卖”的感觉呢(我不要你也塞给我,还要花费我的精力).在这篇中,我们将来一个”私人定制版”的订阅.

其实这种模式没有特别之处,主要是理解下面这个概念就行.

bindings(绑定)和routingKey(路由键)

关于bindings,官网有一段话:

A binding is a relationship between an exchange and a queue. This can be simply read as: the queue is interested in messages from this exchange.

翻译一下: binding 是exchange(转化器)和queue(队列)关系的一种描述,可以简单的被理解为:该队列对这个exchange上的消息感兴趣.

在定义一段关系时,bindings可以带一个routingKey(String类型)的参数,如下:

[code]channel.queueBind(queueName, EXCHANGE_NAME, "hello");


表示该队列只对routingKey为hello的消息感兴趣,而此时的routingKey从何而来呢,别忘了,我们还有一个producer呢,它不正是用来发布消息的吗?

[code]channel.basicPublish(EXCHANGE_NAME, "hello", null, msg.getBytes());


上面这段代码的意思是我要发消息给exchange,并且它的routingKey为hello.其实说白了,就是说: 发消息给exchange时可以指定routingKey,exchange和队列之间可以定义binding,接收者只处理binding和routingKey相同的消息.

这章的代码和上一章的基本不变,就不在这里列出来了.

首先请注意,一旦创建了exchange, RabbitMQ是不允许对其改变的,不然会报错(如图:之前是有一个exchange_fanout的exchange了)



[code]// 报错信息
com.rabbitmq.client.ShutdownSignalException: :channel error; reason: {#method<channel.close>(reply-code=406, reply-text=PRECONDITION_FAILED - inequivalent arg 'type' for exchange 'exchange_fanout' in vhost '/': received 'direct' but current is 'fanout', class-id=40, method-id=10), null, ""}


变动代码:

[code]// 改变exchange名称,上一章是"exchange_fanout",不能同名
private final static String EXCHANGE_NAME = "exchange_direct";
// 定义该exchange的类型为 direct
channel.exchangeDeclare(EXCHANGE_NAME, "direct");
// 发送消息给有routingkey为hello的exchange
channel.basicPublish(EXCHANGE_NAME, "hello", null, msg.getBytes());


消费者变动:

[code]private final static String EXCHANGE_NAME = "exchange_direct";

channel.exchangeDeclare(EXCHANGE_NAME, "direct");
// 确定exchange和队列的binding: hello
channel.queueBind(queueName, EXCHANGE_NAME, "hello");


输出结果如图:





现在稍微变动下消费者的bindings:

[code]// 把bindings变为"world"
channel.queueBind(queueName, EXCHANGE_NAME, "world");


输出结果如下(之前的消费者线程没有关闭):



消费者3676:



消费者6408:



从上面的输出结果可以看到,bindings为hello的接到了消息,而为world的却依旧在等待…direct方式的实验就到此结束啦,下面还会学习下topic的,敬请期待.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: