消息收發
- 消息發送:支持指定同步發送、異步發送;支持身份認證,客戶端連接RabbitMQ服務端時使用SSL或賬號密碼驗證;支持廣播發送;支持發送持久化消息、非持久化消息。
- 消息消費:采用pull方式和push方式消費,多消費者間輪詢消費。
消息發送可靠性
RabbitMQ消息發送可靠性有兩個方法,一個是事務,另一個是Confirm機制。事務能夠解決producer與broker之間消息確認的問題,只有消息成功被broker接受,事務提交才能成功,但會降低RabbitMQ的性能,為此RabbitMQ提供了一種低消耗的事務管理方式,將channel設置成confirm模式。confirm模式的channel,通過該channel發出的消息會生成一個唯一的有序ID(從1開始),一旦消息成功發送到相應的隊列之后,RabbitMQ服務端會發送給生產者一個確認標志,包含消息的ID,這樣生產者就知道該消息已經發送成功了。Confirm支持普通發送方確認模式、批量確認模式、異步監聽發送方確認模式,可以滿足發送可靠性和高性能需求。
消息確認
為了保證消息從隊列可靠地到達消費者,RabbitMQ提供了消息確認機制。
- 消費者訂閱隊列的時候,可以指定autoAck參數,當autoAck為true的時候,RabbitMQ采用自動確認模式,RabbitMQ自動把發送出去的消息設置為確認,然后從內存或者硬盤中刪除,而不管消費者是否真正消費到了這些消息。
- 當autoAck為false的時候,RabbitMQ會等待消費者回復的確認信號,收到確認信號之后才從內存或者磁盤中刪除消息。
消息確認機制是RabbitMQ消息可靠性投遞的基礎,只要設置autoAck參數為false,消費者就有足夠的時間處理消息,不用擔心處理消息的過程中消費者進程掛掉后消息丟失的問題。
消息TTL
Time To Live,也就是生存時間,是一條消息在隊列中的最大存活時間,單位是毫秒。
- RabbitMQ可以對消息和隊列設置TTL。
- RabbitMQ支持設置消息的過期時間,在消息發送的時候可以進行指定,每條消息的過期時間可以不同。
- RabbitMQ支持設置隊列的過期時間,從消息入隊列開始計算,直到超過了隊列的超時時間配置,那么消息會變成死信,自動清除。
- 如果兩種方式一起使用,則過期時間以兩者中較小的那個數值為準。
- 當然也可以不設置TTL,不設置表示消息不會過期;如果設置為0,則表示除非此時可以直接將消息投遞到消費者,否則該消息將被立即丟棄。
持久化
RabbitMQ的持久化分為三個部分:交換器持久化、隊列持久化和消息的持久化。
- 交換器持久化可以通過在聲明隊列時將durable參數設置為true。如果交換器不設置持久化,那么在RabbitMQ服務重啟之后,相關的交換器元數據會丟失,不過消息不會丟失,只是不能將消息發送到這個交換器了。
- 隊列的持久化能保證其本身的元數據不會因異常情況而丟失,但是不能保證內部所存儲的消息不會丟失。要確保消息不會丟失,需要將其設置為持久化。隊列的持久化可以通過在聲明隊列時將durable參數設置為true。
- 設置了隊列和消息的持久化,當RabbitMQ服務重啟之后,消息依然存在。如果只設置隊列持久化或者消息持久化,重啟之后消息都會消失。
對于可靠性不是那么高的消息可以不采用持久化處理以提高整體的吞吐量。在實際中,需要根據實際情況在可靠性和吞吐量之間做一個權衡。
延遲隊列
一般的隊列,消息一旦進入隊列就會被消費者立即消費。延遲隊列就是進入該隊列的消息會被消費者延遲消費,延遲隊列中存儲的對象是的延遲消息,“延遲消息”是指當消息被發送以后,等待特定的時間后,消費者才能拿到這個消息進行消費。RabbitMQ提供TTL配合死信隊列和延時隊列插件兩種方式來滿足延時消息業務場景。
死信隊列
當消息在一個隊列中變成死信之后,他能被重新發送到另一個交換器中,這個交換器成為死信交換器,與該交換器綁定的隊列稱為死信隊列。消息變成死信有下面幾種情況:
- 消息被拒絕
- 消息過期
- 隊列達到最大長度
DLX也是一個正常的交換器,和一般的交換器沒有區別,他能在任何的隊列上面被指定,實際上就是設置某個隊列的屬性。當這個隊列中有死信的時候,RabbitMQ會自動將這個消息重新發送到設置的交換器上,進而被路由到另一個隊列。當發生異常的時候,消息不能夠被消費者正常消費,被加入到了死信隊列中。后續的程序可以根據死信隊列中的內容分析當時發生的異常,進而改善和優化系統。
優先級隊列
優先級隊列是指優先級高的消息往往放在隊列的head頭部,相比低優先級的消息,要優先投遞給消費者進行處理。
在RabbitMQ中,我們可以設置消息的優先級,在發送消息時指定消息的優先級,可以分為10個級別,級別越高優先級越大。當多個消息擁有相同的優先級時,它們按照FIFO的順序排序。
鏡像隊列
Rabbitmq支持鏡像隊列,隊列的多個副本保存在不同實例節點。隊列分為主備角色,對某個 queue 來說,只有 master 對外提供服務,而其他 slave 只提供備份服務,在 master 所在節點不可用時,選出一個 slave 作為新的 master 繼續對外提供服務。無論客戶端的請求打到 master 還是 slave 最終數據都是從 master 節點獲取。
- 當請求打到 master 節點時,master 節點直接將消息返回給 client,同時 master 節點會通過 GM(Guaranteed Multicast)協議將 queue 的最新狀態廣播到 slave 節點。GM 保證了廣播消息的原子性,即要么都更新要么都不更新。
- 當請求打到 slave 節點時,slave 節點需要將請求先重定向到 master 節點,master 節點將將消息返回給 client,同時 master 節點會通過 GM 協議將 queue 的最新狀態廣播到 slave 節點。