RabbitMQ是一個消息隊列,和Kafka以及阿里的ActiveMQ從屬性來說,乾的都是一回事。消息隊列的主要目的實現消息的生產者和消費者之間的解耦,支持多應用之間的異步協調工做html
因爲工做緣由,接觸和使用rabbitmq做爲生產環境下的消息隊列,所以準備寫一些博文,記錄下這個過程當中的收貨;而開篇除了環境搭建以外,就是對於其內部的基本概念進行熟悉和了解了。git
基礎環境搭建能夠參考: 《RabbitMq基礎教程之安裝與測試》github
本文則主要集中在如下幾點:服務器
<!-- more -->異步
首先來一張消息隊列的經典圖,能夠劃分爲三個角色: Producer, Queue, Consumer學習
看到這個模型,若是對JDK的容器有必定的瞭解,很容易能夠想到藉助 ArrayBlockingQueue
或者 ListBlockingQueue
就能夠實現簡易的消息隊列(也就是咱們常說的生產者-消費者模型)測試
其實在生活中,這種模型用得很是多,就好比咱們都會接觸的網購快遞,能夠說是一個典型的消息隊列的case了:編碼
商家不斷的把商品扔給快遞公司(注意不是直接將商品給買家),而快遞公司則將商品根據地質分發對應的買家加密
對上面這個過程進行拆解,能夠映射扮演的角色.net
那麼快遞公司時怎麼知道要把商品給對應的買家呢?根據包裹上的地址+電話
經過上面的實例對比,發現基本的消息隊列定義的元素太少,這裏則正好能夠看一下RabbitMQ是怎麼具體來實現消息隊列的
上面是一些專業的概念,那麼能夠怎麼映射到前面的快遞上呢?
生產者,將消息投遞給Exchange,而後由Exchange將消息路由到對應的Queue上,供消費者消費,那麼這個路由有哪些方式呢?
消息中的路由鍵(routing key)若是和 Binding 中的 binding key 一致, 交換器就將消息發到對應的隊列中
簡單來說,就是路由鍵與隊列名徹底匹配
舉例說明
Exchange和兩個隊列綁定在一塊兒:
從上圖也能夠看出,這種策略,將忽略所謂的routing key,將消息分發到全部綁定的Queue上,更加相似咱們理解的廣播模式
topic 交換器經過模式匹配分配消息的路由鍵屬性,將路由鍵和某個模式進行匹配,此時隊列須要綁定到一個模式上
能夠理解爲直接策略的進階版,直接策略是徹底精確匹配,而topic則支持正則匹配,知足某類指定規則的(如以xxx開頭的路由鍵),能夠鍵消息分發過去
#
匹配0個或多個單詞*
匹配很少很多一個單詞一個更直觀的實例以下
Producer發送消息時須要設置routing_key,
test.orange.mm
消息,則會路由到Q1;而若是是 test.orange
則沒法路由到Q1,由於Q1的規則是三個單詞,中間一個爲orange,不知足這個規則的都無效test.qq.rabbit
或者 lazy.qq
均可以分發到Q2;即路由key爲三個單詞,最後一個爲rabbit或者不限制單詞個數,主要第一個是lazy的消息,均可以分發過來test.orange.rabbit
消息,則Q1和Q2均可以知足這個實際上用得很少,它是根據Message的一些頭部信息來分發過濾Message,忽略routing key的屬性,若是Header信息和message消息的頭信息相匹配
主要使用的消息分發策略有三個,直接,路由和扇形,簡單的小結下應用場景和區別
直接徹底匹配模式,適用於精準的消息分發
Routing Key的匹配模式,支持Routing Key的模糊匹配方式,更適用於多類消息的聚合
忽略Routing Key, 將消息分配給全部的Queue,廣播模式,適用於消息的複用場景
消息隊列的一個重要指標,當有消費者獲取了消息以後,對這個消息我應該怎麼辦?是直接刪除仍是等某個合適的機會再刪除?又或者是乾脆不刪除,就留着了?
在實際的應用場景中,消息正常消費以後,咱們但願的是這個消息就不要了,可是消費的過程當中若是出現了bug,則但願不要刪除消息,等我修復這個bug後,能夠把這個消息從新的投遞給我
Consumer接收到了消息以後,必須返回一個ack的標誌,表示消息是否成功消費,若是返回true,則表示消費成功了,而後這個消息就會從RabbitMQ的隊列中刪掉;若是返回false,且設置爲從新入隊,則這個消息能夠被從新投遞進來
一般實際編碼中,默認是自動ACK的,若是消息的重要性程度較高,咱們應該設置爲主動ACK,在接收到消息以後,自主的返回對應的ACK信息
這一塊更多地內容能夠查看實際使用篇
一灰灰的我的博客,記錄全部學習和工做中的博文,歡迎你們前去逛逛
盡信書則不如,已上內容,純屬一家之言,因我的能力有限,不免有疏漏和錯誤之處,如發現bug或者有更好的建議,歡迎批評指正,不吝感激