amqp協議是乙個提供統一訊息服務的應用層標準協議,並不會受到客戶端/中介軟體不同產品、不同開發語言等條件的影響。rabbitmq則是基於該協議實現的。
舉個例子來說,如下圖,生產者將訊息傳送到交換機上,交換機接收到資訊以後按照相應的路由鍵路由到佇列中,這裡的交換機只是起到了路由的功能,實際上訊息儲存在訊息佇列中,接下來在佇列中的的訊息可以將其散發到消費者或者消費者主動去獲取訊息。
該協議分為三層,分別是module layer、session layer、transport layer,如下圖:
module layer:決定基本域模型所產生的行為,主要定義了一些供客戶端呼叫的命令,客戶端可以利用這些命令實現自己的業務邏輯。
session layer:主要負責將客戶端的命令傳送給伺服器,再將服務端的應答返回給客戶端,主要為客戶端和伺服器之間通訊提供可靠性、同步機制和錯誤處理。
transport layer:主要用於二進位制資料流的傳輸。
我們首先了解一些概念:
broker:接收和分發訊息的應用,像是rabbitmq、zeromq或者redis等等。
connection:publisher/consumer和broker之間的tcp連線
channel:兩個amqp結點之間雙向通訊流,通道是多路復用的,因此單個網路連線可以支撐多個通道,各個通道之間是相互隔離的,其極大的減少了作業系統建立多個tcp連線的開銷。
message:訊息
exchange:伺服器中接收來自生產者程式的訊息的實體,並可選擇將這些訊息路由到伺服器中的訊息佇列中
message queue:儲存訊息並將它們**給消費者
routing key:乙個虛擬位址,虛擬機器可用它來確定如何路由乙個特定訊息
交換機常用的屬性有:
exchange存在多種型別,其中最常使用的包括direct
、fanout
、topic
三種型別,還有一種特殊的headers
,它們分別的用處是:
direct:message中的routing key 如果和binding中的 binding key一致的話,則exchange會將message散發到對應的message queue中。
在預設的情況下建立的就是該型別的exchange,通常使用在需要傳送訊息到具體的佇列的情況,比如下面這張圖中,最後交換機會將訊息路由到名字為green的訊息佇列中。
fanout:exchange會將所有的message散發到關聯的message queue中。
即便是已經提供了routing key,該型別交換機也會忽略掉,並且將訊息傳送到所有關聯的佇列中,通常用來實現發布/訂閱模式,比如說體育新聞**可以用它來近乎實時地將比分更新分發給移動客戶端,分發系統使用它來廣播各種狀態和配置更新等等。
topic:根據正規表示式將message散發到匹配的message queue中。
headers:類似於direct,但是當涉及到多個屬性的時候,乙個routing key 無法完全表達,其只能是個字串,而多屬性需要使用到多個鍵值對表示,因此使用訊息屬性來代替路由鍵作為路由規則,通過判斷訊息頭中的值來和佇列中的值來確定訊息的路由位置。
如果x-match為any的時候, 表示訊息頭的任意乙個值被匹配後就可以滿足條件,而當x-match為 all的時候,表示訊息頭的所有的值都需要被匹配到才能滿足條件,比如在下圖中,因為第乙個隊列為any,並且存在匹配的值,所以可以路由到綠色的路由中,因為第三個隊列為all,訊息頭並沒有都匹配所有的鍵值對,因此訊息只會傳送到綠色的訊息佇列中。
同樣的,和交換機一樣,佇列也有常用的屬性:
這裡需要注意的是,如果在訊息**中佇列並不存在,則會根據宣告去定義;如果已經存在,但是這次宣告的佇列的屬性和之前已經存在的屬性存在差異,則會返回乙個通道級異常!
這裡的持久化設定並不會讓在佇列中的訊息也同樣持久化,其只會在訊息**重啟後重新定義該佇列,如果沒有設定訊息持久化,那麼佇列中的訊息則不會存在。
如果訊息無法路由到具體的佇列中,那麼該訊息可能會被銷毀或是重新返回給發布者,這取決於設定的屬性。
訊息存在三個動作,分別是確認、拒絕、預取
訊息確認存在兩種模式,分別是1. 自動確認模式:訊息佇列傳送完後就銷毀;2.顯示確認模式:在消費者進行確認後再進行銷毀;
在顯示確認模式情況下,如果消費者不幸掛掉了,該機制會使訊息重新回到訊息佇列中,等待下一位消費者。
分為重新放回佇列還是立即銷毀,像是在kombo中,它們分別通過message.requeue()
和message.reject()
實現。
如果在多個消費者共享乙個訊息佇列的情況下,可以在消費者傳送訊息的時候設定預取的訊息個數,起到乙個負載均衡的效果。
連線即connection
,內部則是通過tcp長連線實現,關閉連線時最好優雅的關閉amqp連線,即connection.close()
,而不是簡單粗暴的關閉tcp連線,否則會報出相關的連線錯誤資訊。
如果存在多個連線的情況下,為了避免建立多個tcp而造成系統資源的浪費和超載,因此使用channel
通道,其本質是共享了tcp的連線,將其連線分為多個互不影響的連線通道,從而有效的利用tcp連線。
具體參考官方文件
現在比較流行的訊息佇列有zeromq和rabbitmq,其中zeromq擁有更出色的氫能,不過是建立在允許訊息資料丟失的情況下,適用於高吞吐量/低延遲的應用場景中。與zeromq不同,rabbitmq完全實現了amqp協議,使用上類似於郵箱服務,支援訊息的持久化、事務、擁塞控制、負載均衡等特性,使得rabbitmq擁有更加廣泛的應用場景。
功能rabbitmq
zeromq
訊息持久化
支援不支援
事務支援
不支援類似
郵箱socket效能低
高穩定性
高不穩定
支援amqp協議
支援不支援
適用場景
不允許資料丟失
高吞吐
RabbitMQ 知識總結
amqp協議是乙個提供統一訊息服務的應用層標準協議,並不會受到客戶端 中介軟體不同產品 不同開發語言等條件的影響。rabbitmq則是基於該協議實現的。舉個例子來說,如下圖,生產者將訊息傳送到交換機上,交換機接收到資訊以後按照相應的路由鍵路由到佇列中,這裡的交換機只是起到了路由的功能,實際上訊息儲存...
RabbitMQ知識點總結
1 常用埠 5672 用於常規連線 5671用於tls連線 2 佇列 1 佇列的長度是有限的,佇列和訊息由ttl time to live 存活時間 這兩個功能可以用於資料過期,並且可以設定佇列最多可以使用多少資源。這個功能可以設定訊息的延遲載入 下面詳細介紹 2 訊息訂閱 佇列是有序的訊息集合,訊...
rabbitMq 基礎知識總結
rabbitmq 高階訊息佇列協議 elong 語言開發的 幾個重要的物件 server 也叫boser 就是伺服器 connectionfactory 是connection的製造工廠 connection 封裝了rabbitmq的socket鏈結部分的邏輯 channel 管道我們的大部分業務的...