1.應用場景
- 解耦
- 異步
- 流量消峯
- 日誌記錄
2.重複消息的解決方案
- 消費端處理消息的業務邏輯保持冪等性
- 保證每條消息都有惟一編號且保證消息處理成功與去重表的日誌同時出現
3.有序性
- Producer對於須要順序的消息發送到同一個queue中
- Consumer使用MessageListenerOrderly來對消息進行有序消費
4. 如何實現分佈式事務
- 發送方向 MQ 服務端發送消息。
- MQ Server 將消息持久化成功以後,向發送方 ACK 確認消息已經發送成功,此時消息爲半消息。
- 發送方開始執行本地事務邏輯。
- 發送方根據本地事務執行結果向 MQ Server 提交二次確認(Commit 或是 Rollback),MQ Server 收到 Commit 狀態則將半消息標記爲可投遞,訂閱方最終將收到該消息;MQ Server 收到 Rollback 狀態則刪除半 消息,訂閱方將不會接受該消息。
- 在斷網或者是應用重啓的特殊狀況下,上述步驟4提交的二次確認最終未到達 MQ Server,通過固定時間後 MQ Server 將對該消息發起消息回查。
- 發送方收到消息回查後,須要檢查對應消息的本地事務執行的最終結果。
- 發送方根據檢查獲得的本地事務的最終狀態再次提交二次確認,MQ Server 仍按照步驟4對半消息進行操做。
5.push和pull模式
- push模式:客戶端與服務端創建鏈接後,當服務端有消息時,將消息推送到客戶端。
- pull模式:客戶端不斷的輪詢請求服務端,來獲取新的消息。
- 但在具體實現時,Push和Pull模式都是採用消費端主動拉取的方式,即consumer輪詢從broker拉取消息。
6. pull方式實現,RocketMQ如何保證消息的實時性呢?
長輪詢便是在請求的過程當中,如果服務器端數據並無更新,那麼則將這個鏈接掛起,直到服務器推送新的 數據,再返回,而後進入循環週期。 客戶端像傳統輪詢同樣從服務端請求數據,服務端會阻塞請求不會馬上返回,直到有數據或超時才返回給客 戶端,而後關閉鏈接,客戶端處理完響應信息後再向服務器發送新的請求。java
7. 消息模式
DefaultMQPushConsumer實現了自動保存offset值以及實現多個consumer的負載均衡。服務器
DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("HAOKE_IM")
複製代碼
經過groupname將多個consumer組合在一塊兒,那麼就會存在一個問題,消息發送到這個組後,消息怎麼分配呢? 這個時候,就須要指定消息模式,分別有集羣和廣播模式。負載均衡
- 集羣模式
同一個 ConsumerGroup(GroupName相同) 裏的每 個 Consumer 只消費所訂閱消息的一部份內容, 同 一個 ConsumerGroup 裏全部的 Consumer消費的內容合起來纔是所訂閱 Topic 內容的總體, 從而達到 負載均衡的目的 。
- 廣播模式
同一個 ConsumerGroup裏的每一個 Consumer都 能消費到所訂閱 Topic 的所有消息,也就是一個消息會 被屢次分發,被多個 Consumer消費。
consumer.setMessageModel(MessageModel.CLUSTERING);
consumer.setMessageModel(MessageModel.BROADCASTING);
複製代碼
8. 存儲機制
8.1 消息數據的存儲
在RocketMQ中,消息數據是保存在磁盤文件中,爲了保證寫入的性能,RocketMQ儘量保證順序寫入,順序寫入的效率比隨機寫入的效率高不少。
RocketMQ消息的存儲是由ConsumeQueue和CommitLog配合完成的,CommitLog是真正存儲數據的文件, ConsumeQueue是索引文件,存儲數據指向到物理文件的配置。異步
8.2 同步刷盤與異步刷盤
- 同步刷盤
在返回寫成功狀態時,消息已經被寫入磁盤 。 具體流程是:消息寫入內存的 PAGECACHE 後,馬上通知刷盤線程刷盤,而後等待刷盤完成,刷盤線程 執行完成後喚醒等待的線程,返回消息寫成功的狀態 。
- 異步刷盤
在返回寫成功狀態時,消息可能只是被寫入了內存的 PAGECACHE,寫操做的返回快,吞吐量大 當內存裏的消息量積累到必定程度時,統一觸發寫磁盤動做,快速寫入。
- broker配置文件中指定刷盤方式 flushDiskType=ASYNC_FLUSH -- 異步 flushDiskType=SYNC_FLUSH -- 同步