RabbitMQ 消息

MQ全称为Message Queue, 消息队列(MQ)是一种应用程序对应用程序的通讯方法。MQ是消费-生产者模型的一个典型的表明,一端往消息队列中不断写入消息,而另外一端则能够读取队列中的消息。
一、队列、生产者、消费者缓存

队列是RabbitMQ的内部对象,用于存储消息。生产者(下图中的P)生产消息并投递到队列中,消费者(下图中的C)能够从队列中获取消息并消费。

20170828201708910.pngapp

多个消费者能够订阅同一个队列,这时队列中的消息会被平均分摊给多个消费者进行处理,而不是每一个消费者都收到全部的消息并处理。

二、Exchange、Binding负载均衡

刚才咱们看到生产者将消息投递到队列中,实际上这在RabbitMQ中这种事情永远都不会发生。实际的状况是,生产者将消息发送到Exchange(交换器,下图中的X),再经过Binding将Exchange与Queue关联起来。

三、Exchange Type、Bingding key、routing keycode

在绑定(Binding)Exchange与Queue的同时,通常会指定一个binding key。在绑定多个Queue到同一个Exchange的时候,这些Binding容许使用相同的binding key。

  生产者在将消息发送给Exchange的时候,通常会指定一个routing key,来指定这个消息的路由规则,生产者就能够在发送消息给Exchange时,经过指定routing key来决定消息流向哪里。

  RabbitMQ经常使用的Exchange Type有三种:fanout、direct、topic。

  fanout:把全部发送到该Exchange的消息投递到全部与它绑定的队列中。

  direct:把消息投递到那些binding key与routing key彻底匹配的队列中。

  topic:将消息路由到binding key与routing key模式匹配的队列中。

  附上一张RabbitMQ的结构图:

最后来具体解析一下几个问题:对象

一、能够自动建立队列,也能够手动建立队列,若是自动建立队列,那么是谁负责建立队列呢?是生产者?仍是消费者?队列

若是队列不存在,固然消费者不会收到任何的消息。可是若是队列不存在,那么生产者发送的消息就会丢失。因此,为了数据不丢失,消费者和生产者均可以建立队列。那么若是建立一个已经存在的队列呢?那么不会有任何的影响。须要注意的是没有任何的影响,也就是说第二次建立若是参数和第一次不同,那么该操做虽然成功,可是队列属性并不会改变。

  队列对于负载均衡的处理是完美的。对于多个消费者来讲,RabbitMQ使用轮询的方式均衡的发送给不一样的消费者。

二、RabbitMQ的消息确认机制路由

默认状况下,若是消息已经被某个消费者正确的接收到了,那么该消息就会被从队列中移除。固然也可让同一个消息发送到不少的消费者。

  若是一个队列没有消费者,那么,若是这个队列有数据到达,那么这个数据会被缓存,不会被丢弃。当有消费者时,这个数据会被当即发送到这个消费者,这个数据被消费者正确收到时,这个数据就被从队列中删除。

 那么什么是正确收到呢?经过ack。每一个消息都要被acknowledged(确认,ack)。咱们能够显示的在程序中去ack,也能够自动的ack。若是有数据没有被ack,那么:

 RabbitMQ Server会把这个信息发送到下一个消费者。

 若是这个app有bug,忘记了ack,那么RabbitMQServer不会再发送数据给它,由于Server认为这个消费者处理能力有限。

并且ack的机制能够起到限流的做用(Benefitto throttling):在消费者处理完成数据后发送ack,甚至在额外的延时后发送ack,将有效的均衡消费者的负载。
相关文章
相关标签/搜索