RabbitMq是由erLang語言開發的基於AMQP協議的開源消息隊列。AMQP特徵主要是面向消息,隊列,路由(包括點對點、發佈訂閱),可靠性,安全。AMQP協議更多用在企業系統內,對數據一致性,穩定性和可靠性要求比較高的場景。
核心概念:
- server:又稱爲brocker,接受客戶端的連接實現AMOP實體服務工作
- connection:應用程序與brocker之間的網絡連接
- channel:網絡信道,幾乎所有的操作都在這裏進行,是進行消息讀寫的通道。客戶端可以建立多個通道,每個通道代表一 個會話任務。
- message:消息,服務器和應用程序之間傳送的數據,由properties和body組成。properties可以對消息修飾,比如消息的優先級,延遲性等。body就是消息內容。
- virtual host:虛擬主機地址。用於進行邏輯隔離。最上層的消息路由。一個virtual host 裏面可以有若干個Exchange 和Queue,同一個virtual host不能有相同名稱的Exchange或Queue.
- Exchange:交換機,接受消息,根據路由key轉發消息到綁定的隊列
- bingding:Exchange和Queue之間的虛擬連接,bingding中可以包含 routing key
- Routing key:一個路由規則,虛擬機用它來確定如何路由一個特定消息
- Queue: 消息隊列,保存消息並轉發給消費者
Exchange交換機屬性
- name 交換機名稱
- type 交換機類型,direct,topic,headers,fanout
- Durability 是否需要持久化
- auto delete 當交換機上的隊列刪除後,自動刪除Exchange
- internal 當前Exchange是否用於Rabitmq內部使用,默認爲false
- Arguments 擴展參數,用於擴展AMQP協議自制應用
Message屬性
爲了瞭解消息屬性,我們首先要知道AMQP的Basic.Properties數據結構,因爲每條消息都包含這一結構。
包含在消息頭幀中的消息屬性是一組預定義的值,這些值通過Basic.Properties數據結構指定。如delivery-mode屬性,這一屬性告訴你RabbitMQ保存消息到內存中時,是否應該先存入磁盤。
首先我們介紹一下Basic.Properties的各個基本屬性:
- content-type: 內容體的類型,如application/json
- content-encoding: 壓縮或編碼格式
- message-id和correlation-id: 唯一標識消息和消息響應,用於工作流程中實現消息跟蹤
-timestamp: 減少消息大小,描述消息創建時間
- expiration: 表明消息過期
- delivery-mode: 將消息寫入磁盤或內存隊列
- app-id和user-id: 幫助追蹤出現問題的消息發佈者應用程序
- type: 定義消息類型的自由格式字符串值
- reply-to: 實現響應消息的路由
- headers: 是一個映射表,定義自由格式的屬性和實現rabbitmq路由
高級特性
消息如何保障100%投遞成功?
保障消息的成功發出
保障mq節點的成功接收
發送端收到mq確認應答
完善的消息補償機制:消息落庫狀態打標/消息的延遲投遞,做二次確認,回調檢查
消費端冪等性
唯一ID+指紋鎖機制利用數據庫主鍵去重
利用redis的原子性去實現
Confirem確認機制
- 消息的去人是指生產者投遞消息後,如果broker收到消息,則會給生產者一個應答
- 生產者進行接收應答,用來確定這條消息是否正常達到broker
如何實現確認消息?
第一步在channel上,開啓確認模式。channer.confirmSelect()
第二步在channel上,添加監聽 addConfireListener,監聽成功或者失敗的處理結果
Return消息機制
ReturnListener用於處理一些不可路由的消息
Mandatory如果爲true,則監聽器會接收到路由不可達的消息然後進行後續處理,如果爲false,Broker會自動刪除消息
消費端限流
Rabbitmq提供了一種qos(服務質量保證)功能,即在非自動確認模式下,如果一數目的消息(通過基於consumer或者channel設置Qos的值)未被確認前,不進行新的消息消息。
void BasicQos(uint prefetchSize,ushort prefetchCount,bool global);
死信隊列Dlx-----Dead-letter-Exchange
利用Dlx,當消息在一個隊列中變成死信之後,它能被重新發布到另一個Exchange,這個Exchange就是DLX
死信隊列情況:
消息被拒絕(basic.reject/basic.nack)並且requeue = false
消息TTL過期
隊列達到最大長度
死信隊列的設置