AMQP-RabbitMQ詳解

RabbitMQ是的一個實現了高級隊列協議(AMQP)的消息代理軟件,也稱爲面向消息的中間件,由美國微處理器廠商Rabbit公司開源。RabbitMQ服務器是用Erlang語言編寫的。

我們以RabbitMQ爲例總結AMQP的實現。

一、AMQP定義

AMQP定義了網絡協議和代理服務:

  • 高級消息交換協議模型:一套確定的消息交換功能,必須有三個部分:
    • 交換器(exchange):生產者把消息發到交換器上
    • 隊列(queue):消息到達隊列,等待消費者接收
    • 綁定(binding):決定了消息如何從交換器到指定的隊列
  • 一個網絡線級協議(數據傳輸格式),客戶端應用可以通過這個協議與消息代理和它實現的AMQP模型進行交互通信
  • 可以只實現AMQP協議規範中的的部分語義,但是我們相信明確的描述這些語義有助於理解這個協議

AMQP使得遵從該規範的客戶端應用和消息中間件服務器的全功能互操作成爲可能。

二、隊列的基本動作

隊列(queue)是消息的載體,每個消息都會被投到一個或多個隊列,而queue擁有自己的erlang進程。

  • basic.consume:訂閱消息,將信道設置爲接收模式,知道取消對隊列的訂閱爲止。訂閱模式下,在接收完成上一條消息之後,會自動接收下一條消息
  • basic.get:獲取消息,與訂閱不同,只向隊列獲取一條消息。大致上講,獲取消息會先訂閱消息,獲取單條消息,再取消訂閱,所以不要循環basic.get去代替basic.consume,性能極差
  • basic.ack:確認接收,消費者對消息進行確認,告知客戶端已經消費完成。訂閱模式下,在ack之後會接收下一條消息。對RabbitMQ來說,他不關注消費者是否將消息消費完成,只在意消費者的ack確認,在ack之後纔會將消息從隊列刪除;
    • auto-ack參數:是否自動確認,爲true時,一旦消費者接收消息,RabbitMQ會自動視其爲已ack
  • basic.reject:拒絕接收,消費者拒絕RabbitMQ發送的消息。附帶參數requeue,如果爲true,則將消息重新發送給下一個訂閱者;如果爲false,就會將消息從隊列移除,如果RabbitMQ版本支持死信隊列(DLX,dead letter exchange),則會將消息發佈到DLX中
  • queue.declare:創建隊列,生產者消費者都可以使用該命令,但如果消費者在同一信道上訂閱了另一個隊列的話,必須先取消訂閱,設置信道爲傳輸模式,才能創建。
    • exclusive參數:是否私有,爲true時將隊列變爲私有,只有你的應用程序才能消費隊列消息;
    • auto-delete參數:是否自動刪除,爲true時,當最後一個消費者取消訂閱時,自動移除隊列。

三、交換器與綁定

上述隊列的基本操作可以看出消費者是如何從隊列中獲取消息的,而交換器與綁定的組合,完成了消息到隊列的投遞。

通過交換器與綁定,發佈者不需要關注服務器的另一端的邏輯,通過交換器與綁定的配置,就能夠完成例如發佈-訂閱和多播等複雜的案例。

投遞到RabbitMQ的消息會附帶一個路由鍵(routing key),隊列通過路由綁定到交換器,從而完成消息從交換器到隊列的分發。路由鍵一般使用多個單詞,以 . 進行單詞之間的分隔

AMQP定義了四種不同類型的交換器發揮的作用:

  1. direct:匹配路由鍵,需要將一個隊列綁定到交換機上,要求該消息與一個特定的路由鍵完全匹配。例如:路由鍵 abc 只能匹配到名稱爲 abc 的隊列
  2. fanout:不處理路由鍵,消息會發送到所有與交換器綁定的隊列上
  3. topic:將路由鍵進行模式匹配,將消息發送到匹配的隊列上。# 代表匹配 n 個詞,n > 0,* 則匹配一個詞。例如:abc.* 匹配 abc.d,不匹配 abc.d.e,單獨的#匹配所有隊列。在不使用匹配符的情況下,topic與direct相同
  4. headers:允許匹配消息的header,其他方面跟direct交換器完全一致,相較其他三種性能偏低,也不怎麼實用。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章