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

本文介绍了RabbitMQ中direct类型的exchange,对比fanout模式,讲解了如何实现“私人定制版”订阅。通过bindings和routingKey的概念,说明了消费者如何根据routingKey选择性接收消息。文中提供了代码示例,展示了不同bindings设置下消费者接收消息的情况。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

参考http://blog.youkuaiyun.com/lmj623565791/article/details/37620057和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类型)的参数,如下:

channel.queueBind(queueName, EXCHANGE_NAME, "hello");

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

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

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

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


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

// 报错信息
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, ""}

变动代码:

// 改变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());

消费者变动:

private final static String EXCHANGE_NAME = "exchange_direct";

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

输出结果如图:
生产者

消费者3676

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

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

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

消费者3676:
消费者3676

消费者6408:
消费者6408

从上面的输出结果可以看到,bindings为hello的接到了消息,而为world的却依旧在等待…direct方式的实验就到此结束啦,下面还会学习下topic的,敬请期待.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值