目錄
消息存儲
消息存儲方式
非持久化
- 消息生成者發(fā)送消息到 MQ
- MQ 返回 ACK(Acknowledge Character)給生產者
- MQ push 消息給對應的消費者
- 消息消費者返回 ACK 給 MQ
持久化
- 消息生成者發(fā)送消息到 MQ
- MQ 收到消息,將消息進行持久化尝江,存儲該消息
- MQ 返回 ACK 給生產者
- MQ push 消息給對應的消費者
- 消息消費者返回 ACK 給 MQ
- MQ 刪除消息
注意:
①第 5 步 MQ 在指定時間內接到消息消費者返回 ACK涉波,MQ 認定消息消費成功,執(zhí)行 6 炭序。
②第 5 步 MQ 在指定時間內未接到消息消費者返回 ACK怠蹂,MQ 認定消息消費失敗,重新執(zhí)行 4少态、5、6 易遣。
消息存儲介質
數據庫
- 實現:ActiveMQ
- 缺點:數據庫瓶頸將成為 MQ 瓶頸
文件系統(tǒng)
- 實現:RocketMQ/Kafka/RabbitMQ
- 解決方案:采用消息刷盤機制進行數據存儲
- 缺點:硬盤損壞的問題無法避免
消息存儲與讀寫方式
SSD(Solid State Disk):固態(tài)硬盤
- 隨機寫(100 KB/s)
- 順序寫(600 M B/s):1秒1部電影
Linux 系統(tǒng)發(fā)送數據的方式
- “零拷貝”技術數據傳輸由傳統(tǒng)的 4 次復制簡化成 3 次復制侨歉,減少 1 次復制過程Java 語言中使用 MappedByteBuffer 類實現了該技術要求:預留存儲空間,用于保存數據(1G 存儲空間起步)
消息存儲結構
如圖所示倦挂,MQ 數據存儲區(qū)域包含如下內容:
- 消息數據存儲區(qū)域topicqueueIdmessage
- 消費邏輯隊列minOffsetmaxOffsetconsumerOffset
- 索引key 索引創(chuàng)建時間索引……
刷盤機制
同步刷盤
- 生產者發(fā)送消息到 MQ没炒,MQ 接到消息數據
- MQ 掛起生產者發(fā)送消息的線程
- MQ 將消息數據寫入內存
- 內存數據寫入硬盤
- 磁盤存儲后返回 SUCCESS
- MQ 恢復掛起的生產者線程
- 發(fā)送 ACK 到生產者
異步刷盤
- 生產者發(fā)送消息到 MQ,MQ 接到消息數據
- MQ 將消息數據寫入內存
- 發(fā)送 ACK 到生產者
小結
- 同步刷盤 :安全性高先匪,效率低种吸,速度慢(適用于對數據安全要求較高的業(yè)務)
- 異步刷盤 :安全性低,效率高呀非,速度快(適用于對數據處理速度要求較高的業(yè)務)
# 刷盤方式
#- ASYNC_FLUSH 異步刷盤
#- SYNC_FLUSH 同步刷盤
flushDiskType=SYNC_FLUSH
高可用
高可用實現
nameserver
- 無狀態(tài) + 全服務器注冊
消息服務器
- 主從架構(2M-2S)
消息生產
- 生產者將相同的 topic 綁定到多個 group 組骨稿,保證即使 broker master 掛掉,其他 master 仍可正常進行消息接收。
消息消費
- RocketMQ 自身會根據 broker master 的壓力確認是否由 master 承擔消息讀取的功能坦冠,當 master 繁忙時候形耗,自動切換由 slave 承擔數據讀取的工作。
主從復制
同步復制:
- master 接到消息后辙浑,先復制到 slave激涤,然后反饋給生產者寫操作成功
- 優(yōu)點:數據安全,不丟數據判呕,出現故障容易恢復
- 缺點:影響數據吞吐量倦踢,整體性能低
異步復制:
- master 接到消息后鸯乃,立即返回給生產者寫操作成功癌淮,當消息達到一定量后再異步復制到slave
- 優(yōu)點:數據吞吐量大,操作延遲低无虚,性能高
- 缺點:數據不安全边涕,會出現數據丟失的現象晤碘,一旦 master 出現故障,從上次數據同步到故障時間的數據將丟失
配置方式:
#Broker 的角色
#- ASYNC_MASTER 異步復制Master
#- SYNC_MASTER 同步雙寫Master
#- SLAVE
brokerRole=SYNC_MASTER
負載均衡
Producer 負載均衡:
- 內部實現了不同 broker 集群中對同一 topic 對應消息隊列的負載均衡
Consumer 兩種負載均衡策略:
- 平均分配
- 循環(huán)平均分配
消息重試
當消息消費后未正常返回消費成功的信息將啟動消息重試機制
兩種消息重試機制:
- 順序消息重試
- 無序消息重試
順序消息重試
- 當消費者消費消息失敗后功蜓,RocketMQ 會自動進行消息重試(每次間隔時間為 1 秒)园爷。
- 注意:應用會出現消息消費被阻塞的情況,因此式撼,要對順序消息的消費情況進行監(jiān)控童社,避免阻塞現象的發(fā)生。
無序消息重試
- 無序消息包括普通消息美浦、定時消息灭抑、延時消息、事務消息抵代。
- 無序消息重試僅適用于負載均衡(集群)模型下的消息消費腾节,不適用于廣播模式下的消息消費。
- 為保障無序消息的消費荤牍,MQ 設定了合理的消息重試間隔時長案腺。
死信隊列
概念:
- 當消息消費重試到達了指定次數(默認 16 次)后,MQ 將無法被正常消費的消息稱為死信消息(Dead-Letter Message)晦嵌。
- 死信消息不會被直接拋棄同辣,而是保存到了一個全新的隊列中拷姿,該隊列稱為死信隊列(Dead-Letter Queue)。
死信隊列的特征:
- 歸屬某一個組(Gourp Id)旱函,而不歸屬 Topic响巢,也不歸屬消費者。
- 一個死信隊列中可以包含同一個組下的多個 Topic 中的死信消息棒妨。
- 死信隊列不會進行默認初始化踪古,當第一個死信出現后,此隊列首次初始化券腔。
死信隊列中的消息的特征:
- 不會被再次重復消費伏穆。
- 死信隊列中的消息有效期為 3 天,達到時限后將被清除纷纫。
死信處理:
- 在監(jiān)控平臺中枕扫,通過查找死信,獲取死信的 messageId辱魁,然后通過 id 對死信進行精準消費烟瞧。
消息冪等
消息重復消費
消息重復消費原因:
- 生產者發(fā)送了重復的消息網絡閃斷生產者宕機
- 消息服務器投遞了重復的消息網絡閃斷
- 動態(tài)的負載均衡過程網絡閃斷/抖動broker重啟訂閱方應用重啟(消費者)客戶端擴容客戶端縮容
消息冪等
對同一條消息只泼,無論消費多少次剖笙,結果保持一致,稱為消息冪等性请唱。
解決方案:
- 使用業(yè)務 id 作為消息的 key 弥咪。
- 在消費消息時,客戶端對 key 做判定十绑,未使用過放行聚至,使用過拋棄。
- 注意:messageId 由 RocketMQ 產生本橙,messageId 并不具有唯一性扳躬,不能作用冪等判定條件。
常見的冪等方法示例:
- 新增(不冪等):insert into order values(……)
- 查詢(冪等)
- 刪除(冪等):delete from 表 where id=1
- 修改(不冪等):update account set balance = balance+100 where no=1
- 修改(冪等):update account set balance = 100 where no=1