AMQP及RabbitMQ概論

初識消息中間件中,我們瞭解到了消息中間件的編年史,如下
在這裏插入圖片描述

然後我們在介紹ActiveMQ就先簡單的介紹了JMS的規則,所以這裏我們在介紹RabbitMQ的時候,那麼肯定也是先來了解一下AMQP


AMQP,即Advanced Message Queuing Protocol,一個提供統一消息服務的應用層標準高級消息隊列協議。是應用層協議的一個開放標準,爲面向消息的中間件設計。基於此協議的客戶端與消息中間件可傳遞消息,並不受客戶端/中間件不同產品,不同的開發語言等條件的限制。目標是實現一種在全行業廣泛使用的標準消息中間件技術,以便降低企業和系統集成的開銷,並且向大衆提供工業級的集成服務。主要實現有RabbitMQ。


要素

其包括的要素:生產者、消費者、消息、信道、交換器、隊列、綁定、路由鍵。


生產者、消費者、消息

  • 生產者: 消息的創建者,發送到RabbitMQ
  • 消費者: 連接到RabbitMQ,訂閱到隊列上,消費消息,持續訂閱(basicConsumer)和單條訂閱(basicGet)
  • 消息: 包含有效載荷標籤,有效載荷指要傳輸的數據,標籤描述了有效載荷,並且RabbitMQ用它來決定誰獲得消息,消費者只能拿到有效載荷,並不知道生產者是誰。

這裏生產者和消費者的概念其實和ActiveMQ中的類似,只有消息的概念不同,這裏生產者發送給RabbitMQ的消息是有兩部分組成——有效載荷、標籤,其中標籤並不會被消費者拿到,只用於RabbitMQ來進行判斷的。


信道

信道是生產者消費者與RabbitMQ通信的渠道,生產者publish或是消費者subscribe一個隊列都是通過信道來通信的。信道是建立在TCP連接上的虛擬連接,什麼意思呢?


就是說RabbitMQ在一條TCP上建立成百上千個信道來達到多個線程處理,這個TCP被多個線程共享,每個線程對應一個信道,信道在RabbitMQ都有唯一的ID ,保證了信道私有性,對應上唯一的線程使用。


那麼爲什麼RabbitMQ不直接多個TCP連接呢,因爲RabbitMQ爲了保證性能,系統爲每個線程開闢一個TCP是非常消耗性能,每秒成百上千的建立銷燬TCP會嚴重消耗系統。所以RabbitMQ選擇建立多個信道(建立在tcp的虛擬連接)連接到RabbitMQ上。


交換器、隊列、綁定、路由鍵

隊列通過路由鍵(routing key,某種確定的規則)綁定到交換器,生產者將消息發佈到交換器,交換器根據綁定的路由鍵將消息路由到特定隊列,然後由訂閱這個隊列的消費者進行接收。
在這裏插入圖片描述

如果消息達到無人訂閱的隊列會怎麼辦? 消息會一直在隊列中等待,RabbitMq默認隊列是無限長度的。

多個消費者訂閱到同一隊列怎麼辦? 消息以循環的方式發送給消費者,每個消息只會發送給一個消費者。

消息路由到了不存在的隊列怎麼辦? 一般情況下RabbitMQ會直接忽略,當這個消息不存在,也就是消息丟了。




消息的確認

消費者收到的每一條消息都必須進行確認(自動確認和自行確認)。


消費者在聲明隊列時,可以指定autoAck參數,當autoAck=false時,RabbitMQ會等待消費者顯式發回ack信號後才從內存(和磁盤,如果是持久化消息的話)中移去消息。否則,RabbitMQ會在隊列中消息被消費後立即刪除它。


採用消息確認機制後,只要令autoAck=false,消費者就有足夠的時間處理消息(任務),不用擔心處理消息過程中消費者進程掛掉後消息丟失的問題,因爲RabbitMQ會一直持有消息直到消費者顯式調用basicAck爲止。


autoAck=false時,對於RabbitMQ服務器端而言,隊列中的消息分成了兩部分:一部分是等待投遞給消費者的消息;一部分是已經投遞給消費者,但是還沒有收到消費者ack信號的消息。如果服務器端一直沒有收到消費者的ack信號,並且消費此消息的消費者已經斷開連接,則服務器端會安排該消息重新進入隊列,等待投遞給下一個消費者(也可能還是原來的那個消費者)。


RabbitMQ不會爲未ack的消息設置超時時間,它判斷此消息是否需要重新投遞給消費者的唯一依據是消費該消息的消費者連接是否已經斷開。這麼設計的原因是RabbitMQ允許消費者消費一條消息的時間可以很久很久。




交換器類型

交換器的作用是什麼呢?我們可以看到上述的流程圖,其中消費者是從隊列中獲取消息的,可以多個不同的隊列,和ActiveMQ不同的是生產者發送消息並不是直接發送到隊列之中供消費者消息的,而是發送到交換器中,然後由根據綁定的路由鍵將消息路由到不同隊列,然後消費者纔可以進行消費。


交換器類型共有四種Direct、Fanout、Topic、Headers,其中Headers幾乎和direct一樣。


Direct Exchange

路由鍵完全匹配,消息被投遞到對應的隊列,和ActiveMQ的Queue模式類似。每個amqp的實現都必須有一個Direct交換器,包含一個空白字符串名稱的默認交換器。聲明一個隊列時,會自動綁定到默認交換器,並且以隊列名稱作爲路由鍵。
在這裏插入圖片描述


Fanout Exchange

消息廣播到綁定的隊列,這個和ActiveMQ的Topic模式就很比較類似的。
在這裏插入圖片描述


Topic Exchange

這個和我們在ActiveMQ通配符式訂閱比較類似
在這裏插入圖片描述

而AMQP中通過使用 *# ,使來自不同源頭的消息到達同一個隊列,. 將路由鍵分爲了幾個標識符, * 匹配1個,# 匹配一個或多個。
在這裏插入圖片描述
從上述我們就可以發現 # 和在ActiveMQ通配符式訂閱介紹的 > 類似,然後 * 和ActiveMQ中也是類似的,只能匹配一個,不能多個。




虛擬主機

虛擬主機(vhost),其本質上就是一個mini版的MQ服務器,有自己的隊列、交換器和綁定,最重要的,自己的權限機制。


虛擬主機提供了邏輯上的分離,可以將衆多客戶端進行區分,又可以避免隊列和交換器的命名衝突。虛擬主機必須在連接時指定,RabbitMQ包含缺省vhost:"/",通過缺省用戶和口令guest進行訪問。


RabbitMQ裏創建用戶,必須要被指派給至少一個虛擬主機,並且只能訪問被指派內的隊列、交換器和綁定。虛擬主機必須通過RabbitMQ的管理控制工具創建。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章