上文我们实现了一个简单的hello world的案例,我们看到了推送和消费的整个过程。在代码中,有很多的设置我们没有讲明白,这些设置是做什么的呢?又觉得了什么?本文会详细讲明白
消息传递的简单模型
在我们上一个案例中,我们可以了解到如下的一个大概的消息传递模型。我们可以看到消息的传递,其实就是一个端发送到了另一个端口,很简单。
但是我们消息中间件的消息传递这么简单吗?肯定不是的,假若我们有多个生产端,同时又有多个消费端我们怎么保证我们的生产者生产的消息,干好是某个消费者所需要的消息呢?
所以我们看到RabbitMQ提供的消息模型是这样的
如果消息中间件的模型是第一个图,我们的代码肯定不需要那么多的设置,直接推送给某个地址一个消息节课,但是如果是第二个图那我们的代码可能就要做一些设置来选择和适应这样的模型了
模型图流程在代码中的体现
我可以在模型图中看到几个概念
- 生产者 Product
ProductTest.class
- 消费者 Consumer
ConsumerTest.class
- 队列 Queue
channel.exchangeDeclare(EXCHANGE_NAME, "direct", true, false, null);
这几个符合我们的第一个图的理念,但是我们的第二个图中的Exchange是啥呢?
交换器、路由器Exchange
生产者产生消息,然后由交换器、路由器Exchange推送到对应的队列里面。其实这个过程中还有一个RoutingKey
RoutingKey:路由键。生产者将消息发给交换器的时候,一般会指定一个RoutingKey。用来指定这个消息的路由规则,而这个RoutingKey需要与交换器类型和绑定键(BindingKey)合使用才能最终生效。
Binding: 绑定RabbitMQ中通过绑定将交换器与队列关联起来,在绑定的时候一般会指定一 绑定键BindingKey,这样RabbitMQ 就知 何正确将消息路由队列了
在我们代码中,可以明显的看到Exchange和RoutingKey已经BindingKey这样的体现
// 创建一个 type="direct" 、持久化的、非自动删除的交换器
channel.exchangeDeclare(EXCHANGE_NAME, "direct", true, false, null);
// 将交换器与队列通过路由键绑定
channel.queueBind(QUEUE_NAME, EXCHANGE_NAME, ROUTING_KEY);
总结
从这样一个流程我们不难看出,一个消息的生产经过了一系列的设定,然后根据设定才会有效的被对应的consumer
消息在整个流程里,经历了从生产到-> Exchange 再到-> Queue 最后才会到-> consumer