簡介
RabbitMQ是一個開源的消息代理和隊列服務器,用來通過普通協議在不同的應用之間共享數據(跨平台跨語言)。RabbitMQ是使用Erlang語言編寫,並且基於AMQP協議實現。
消息總線(Message Queue),是一種跨進程、異步的通信機制,用於上下游傳遞消息。由消息系統來確保消息的可靠傳遞。
作用
1.異步處理場景說明:
用戶注冊后,需要發注冊郵件和注冊短信。

2.應用解耦
場景說明:用戶下單后,訂單系統需要通知庫存系統。傳統的做法是,訂單系統調用庫存系統的接口。
3.流量削鋒
流量削鋒也是消息隊列中的常用場景,一般在秒殺或團搶活動中使用廣泛。
應用場景:秒殺活動,一般會因為流量過大,導致流量暴增,應用掛掉。為解決這個問題,一般需要在應用前端加入消息隊列。

4.日志處理:
日志處理是指將消息隊列用在日志處理中,比如Kafka的應用,解決大量日志傳輸的問題。
5.消息通訊
優勢

劣勢

AMQP高級消息隊列協議
AMQP(Advanced Message Queuing Protocol) 高級消息隊列協議:高級消息隊列協議。它是應用層協議的一個開放標准,為面向消息的中間件設計,基於此協議的客戶端與消息中間件可傳遞消息,並不受產品、開發語言等條件的限制。
AMQP中增加了Exchange和Binging的角色。生產者把消息發布到Exchange上,消息最終到達隊列並被消費者接收,而Binding決定交換器的消息應該發送到哪個隊列。
架構圖和解釋


* Broker : 標識消息隊列服務器實體rabbitmq-server
* v-host : Virtual Host 虛擬主機。標識一批交換機、消息隊列和相關對象。虛擬主機是共享相同的身份認證和加密環境的獨立服務器域。每個vhost本質上就是一個mini版的RabbitMQ服務器,擁有自己的隊列、交換器、綁定和權限機制。vhost是AMQP概念的基礎,必須在鏈接時指定,RabbitMQ默認的vhost是 /。
* Exchange: 交換器用來接收生產者發送的消息並將這些消息路由給服務器中的隊列。
* Queue : 消息隊列,用來保存消息直到發送給消費者。它是消息的容器,也是消息的終點。一個消息可投入一個或多個隊列。消息一直在隊列里面,等待消費者連接到這個隊列將其取走。
* Banding : 綁定,用於消息隊列和交換機之間的關聯。一個綁定就是基於路由鍵將交換機和消息隊列連接起來的路由規則,所以可以將交換器理解成一個由綁定構成的路由表。
* Channel : 信道,多路復用連接中的一條獨立的雙向數據流通道。信道是建立在真實的TCP連接內地虛擬鏈接,AMQP命令都是通過信道發出去的,不管是發布消息、訂閱隊列還是接收消息,這些動作都是通過信道完成。因為對於操作系統來說,建立和銷毀TCP都是非常昂貴的開銷,所以引入了信道的概念,以復用一條TCP連接。
多種Exchange類型
https://github.com/yourZhang/study_java/tree/master/springboot-rabbitMq/rabbitmq-client01 配置和測試代碼
· 簡單模式/"Hello World!"
生產者將消息交給默認的交換機(AMQP default),交換機將獲取到的信息綁定這個生產者對應的隊列上,監聽當前隊列的消費者獲取消息,執行消息消費。
這種模式只需要創建隊列,使用默認的交換器進行路由。
· 工作模式 / Work queues

生產者將消息交給默認的交換機(AMQP default),交換機將獲取到的信息綁定這個生產者對應的隊列. 由於監聽這個隊列的消費者較多,並且消息只能有一個被消費,就會造成消息競爭。多個隊列綁定默認的交換器,交換器會采用輪詢的方式進行推送。
· fanout / (Publish/Subscribe) / 發布訂閱

生產者將消息給交換機,交換機根據自身的類型(fanout)將會把所有消息復制同步到所有與其綁定的隊列,每個隊列可以有一個消費者接收消息進行消費邏輯。需要我們自己創建交換器並進行綁定,創建多個隊列進行綁定即可,若一個消費者綁定多個隊列則進行輪詢,因為mq有閱后即焚的特點,只能保證一個消費者閱讀接受。常用於群發消息。
·路由模式 / Routing / direct

生產者將消息發送到交換機信息攜帶具體的路由key,交換機的類型是direct,將接收到的信息中的routingKey,比對與之綁定的隊列routingkey。消費者監聽一個隊列,獲取消息,執行消費邏輯。一個隊列可以綁定一個routingKey也可以綁定多個。在消息進行路由時會攜帶一個routingKey尋找對應的隊列。
·/ 通配符匹配

生產者發送消息,消息中帶有具體的路由key,交換機的類型是topic,隊列綁定交換機不在使用具體的路由key而是一個范圍值,例如: *.yell.*,hlll.iii,jjj.#。其中* 表示一個字符串(不能攜帶特殊字符)#表示任意
