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,將有效的均衡消費者的負載。
相關文章
相關標籤/搜索