github(入門簡易版)
消息隊列
- 爲什麼使用消息隊列?消息隊列有什麼優點和缺點?Kafka、ActiveMQ、RabbitMQ、RocketMQ 都有什麼優點和缺點?
- 如何保證消息隊列的高可用?
- 如何保證消息不被重複消費?(如何保證消息消費的冪等性)
- 如何保證消息的可靠性傳輸?(如何處理消息丟失的問題)
- 如何保證消息的順序性?
- 如何解決消息隊列的延時以及過期失效問題?消息隊列滿了以後該怎麼處理?有幾百萬消息持續積壓幾小時,說說怎麼解決?
- 如果讓你寫一個消息隊列,該如何進行架構設計啊?說一下你的思路。
石衫的架構筆記(進階版)
MQ的基本使用和原理(三大經典入門問題)
3.哥們,消息中間件在你們項目裏是如何落地的?
---- 系統可用性降低:涉及到了MQ掛掉之後的高可用保障方案。可以參考一下:
-
通過這兩篇文章,具體看看我們在各種場景下遇到MQ故障採取的高可用降級方案。
----- 系統穩定性降低:系統穩定性可能會下降,故障會增多,需要爲了解決各種MQ引發的技術問題,採取很多的技術方案。
關於這個,我們後面會用專門的文章聊聊MQ中間件的這些問題的解決方案,包括:
-
消息高可靠傳遞(0丟失)
-
消息冪等性傳遞(絕對不重複)
-
百萬消息積壓的線上故障處理
-----分佈式一致性問題(參考上面的“最終一致性分佈式事務的99.99%。。。”)
消息中間件的【消費端】如何保證數據不丟失的一整套技術方案解析:
----以下分別從消費者突然宕機可能導致數據丟失,以及集羣突然崩潰可能導致的數據丟失兩個角度討論了一下數據如何不丟失:
扎心!線上服務宕機時,如何保證數據100%不丟失?(消費者部分取消ack自動確認機制)
消息中間件集羣崩潰,如何保證百萬生產數據不丟失?(MQ的queue持久化+消息持久化)
----如何保證消息中間件全鏈路數據100%不丟失(1)【引出方案:生產者部分ack機制確保消息一定持久化落地到了磁盤】
----如何保證消息中間件全鏈路數據100%不丟失(2)【具體的手動ack機制,核心是channel+delivery tag,以及通知mq的nack機制,即失敗不確認,讓mq發消息給其他消費者】
----消息中間件如何實現消費吞吐量的百倍優化?(主要是unack的積壓問題,從而引出channle中的prefetch count的概念)
總結:如果你是基於RabbitMQ來做消息中間件的話,消費端的代碼裏,必須考慮三個問題:手動ack、處理失敗的nack、prefetch count的合理設置。這三個問題背後涉及到了各種機制:
自動ack機制
delivery tag機制
ack批量與異步提交機制
消息重發機制
手動nack觸發消息重發機制
prefetch count過大導致內存溢出問題
prefetch count過小導致吞吐量過低
消息中間件的【生產端】如何保證數據不丟失的,相關技術方案:
具體解決方案:
1.引出了confirm機制,接着探究confirm機制投遞消息的高延遲性問題。
2.首先,用來臨時存放未ack消息的存儲需要承載高併發寫入,但不需要複雜的運算操作,這種存儲首選絕對不是MySQL之類的數據庫,而建議採用kv存儲。kv存儲承載高併發能力極強,而且kv操作性能很高。
其次,投遞消息之後等待ack的過程必須是異步的,也就是類似上面那樣的代碼,已經給出了一個初步的異步回調的方式。
所以,整體解決confirm的高延遲的方案就是:kv存儲未ack消息+channle的confirm監聽器
但是,像我們上面這樣從生產者到消費者的一套方案就能真的能做到100%數據不丟失嗎?考慮以下情況:
生產端投遞了消息到MQ,而且持久化到磁盤並且回傳ack給生產端了。但是此時MQ還沒投遞消息給消費端,結果MQ部署的機器突然宕機。
參考的方案就是用MQ的集羣機制,給一個數據做多個副本(即RabbitMQ的鏡像集羣機制)【類似kafka的topic+partition機制】
消息中間件優化
面試官:如果讓你設計一個消息中間件,如何將其網絡通信性能優化10倍以上?(kafka:batch機制 + request 機制)
解析:他會在客戶端放一個內存緩衝區,每次你寫一條訂單(消息/partition)先放到內存緩衝區裏去,然後在內存緩衝區裏,會把多個訂單給打包起來成爲一個batch;通過這種多個batch打包成一個request一次性發往Broker的方式,又進一步提升了網絡通信的效率和性能。
支撐百萬連接的系統應該如何設計其高併發架構?(參考kafka的設計思想,reactor連接多路複用)