歡迎關注我的公衆號:石杉的架構筆記(ID:shishan100)面試
週一至週五早8點半!精品技術文章準時送上!算法
這篇文章,咱們來聊聊在線上生產環境使用消息中間件技術的時候,從前到後的全鏈路到底如何保證數據不能丟失。緩存
這個問題,在互聯網公司面試的時候高頻出現,並且也是很是現實的生產環境問題。性能優化
若是你的簡歷中寫了本身熟悉MQ技術(RabbitMQ、RocketMQ、Kafka),並且在項目裏有使用的經驗,那麼很是實際的一個生產環境問題就是:投遞消息到MQ,而後從MQ消費消息來處理的這個過程,數據到底會不會丟失。網絡
面試官此時會問:若是數據會丟失的話,大家項目生產部署的時候,是經過什麼手段保證基於MQ傳輸的數據100%不會丟失的?麻煩結合大家線上使用的消息中間件來具體說說大家的技術方案。架構
這個其實就是很是區分面試候選人技術水平的一個問題。併發
實際上至關大比例的普通工程師,哪怕是在一些中小型互聯網公司裏工做過的,也就是基於公司部署的MQ集羣簡單的使用一下罷了,可能代碼層面就是基本的發送消息和消費消息,基本沒考慮太多的技術方案。分佈式
可是實際上,對於MQ、緩存、分庫分表、NoSQL等各式各種的技術以及中間件在使用的時候,都會有對應技術相關的一堆生產環境問題。微服務
那麼針對這些問題,就必需要有相對應的一整套技術方案來保證系統的健壯性、穩定性以及高可用性。高併發
因此其實中大型互聯網公司的面試官在面試候選人的時候,若是考察對MQ相關技術的經驗和掌握程度,十有八九都會拋出這個使用MQ時必定會涉及的數據丟失問題。由於這個問題,可以很是好的區分候選人的技術水平。
因此這篇文章,咱們就來具體聊聊基於RabbitMQ這種消息中間件的背景下,從投遞消息到MQ,到從MQ消費消息出來,這個過程當中有哪些數據丟失的風險和可能。
而後咱們再一塊兒來看看,應該如何結合MQ自身提供的一些技術特性來保證數據不丟失?
首先給大夥一點提醒,有些新同窗可能還對MQ相關技術不太瞭解,建議看一下以前的MQ系列文章,看看MQ的基本使用和原理:
「Java進階面試系列之一」大家系統架構中爲什麼要引入消息中間件?
「Java進階面試系列之二」系統架構引入消息中間件有什麼缺點
「Java進階面試系列之三」消息中間件在大家項目裏是如何落地的?
另外,其實以前咱們有過2篇文章是討論消息中間件的數據不丟失問題的。
咱們分別從消費者忽然宕機可能致使數據丟失,以及集羣忽然崩潰可能致使的數據丟失兩個角度討論了一下數據如何不丟失。
只不過僅僅那兩個方案還沒法保證全鏈路數據不丟失,可是你們若是沒看過的建議也先回過頭看看:
總之,但願對MQ不太熟悉的同窗,先把前面那些系列文章熟悉一下,而後再來一塊兒系統性的研究一下MQ數據如何作到100%不丟失。
通過以前幾篇文章的討論,目前咱們已經初步知道,第一個會致使數據丟失的地方,就是消費者獲取到消息以後,沒有來得及處理完畢,本身直接宕機了。
此時RabbitMQ的自動ack機制會通知MQ集羣這條消息已經處理好了,MQ集羣就會刪除這條消息。
那麼這條消息不就丟失了麼?不會有任何一個消費者處理到這條消息了。
因此以前咱們詳細討論過,經過在消費者服務中調整爲手動ack機制,來確保消息必定是已經成功處理完了,纔會發送ack通知給MQ集羣。
不然沒發送ack以前消費者服務宕機,此時MQ集羣會自動感知到,而後重發消息給其餘的消費者服務實例。
這篇文章,詳細討論了這個問題,手動ack機制之下的架構圖以下所示:
當時除了這個數據丟失問題以外,還有另一個問題,就是MQ集羣自身若是忽然宕機,是否是會致使數據丟失?
默認狀況下是確定會的,由於queue和message都沒采用持久化的方式來投遞,因此MQ集羣重啓會致使部分數據丟失。
這篇文章,咱們分析瞭如何採用持久化的方式來建立queue,同時採用持久化的方式來投遞消息到MQ集羣,這樣MQ集羣會將消息持久化到磁盤上去。
此時若是消息還沒來得及投遞給消費者服務,而後MQ集羣忽然宕機了,數據是不會丟失的,由於MQ集羣重啓以後會自動從磁盤文件里加載出來沒投遞出去的消息,而後繼續投遞給消費者服務。
一樣,該方案沉澱下來的系統架構圖,以下所示:
你們想想,到目前爲止,我們的架構必定能夠保證數據不丟失了嗎?
其實,如今的架構,仍是有一個數據可能會丟失的問題。
那就是上面做爲生產者的訂單服務把消息投遞到MQ集羣以後,暫時還駐留在MQ的內存裏,還沒來得及持久化到磁盤上,同時也還沒來得及投遞到做爲消費者的倉儲服務。
此時要是MQ集羣自身忽然宕機,咋辦呢?
尷尬了吧,駐留在內存裏的數據是必定會丟失的,咱們來看看下面的圖示。
如今,咱們須要考慮的技術方案是:訂單服務如何保證消息必定已經持久化到磁盤?
實際上,做爲生產者的訂單服務把消息投遞到MQ集羣的過程是很容易丟數據的。
好比說網絡出了點什麼故障,數據壓根兒沒傳輸過去,或者就是上面說的消息剛剛被MQ接收可是還駐留在內存裏,沒落地到磁盤上,此時MQ集羣宕機就會丟數據。
因此首先,咱們得考慮一下做爲生產者的訂單服務要如何利用RabbitMQ提供的相關功能來實現一個技術方案。
這個技術方案須要保證:只要訂單服務發送出去的消息確認成功了,此時MQ集羣就必定已經將消息持久化到磁盤了。
咱們必須實現這樣的一個效果,才能保證投遞到MQ集羣的數據是不會丟失的。
這裏咱們須要研究的技術細節是:倉儲服務手動ack保證數據不丟失的實現原理。
以前,筆者就收到不少同窗提問:
倉儲服務那塊究竟是如何基於手動ack就能夠實現數據不丟失的? RabbitMQ底層實現的細節和原理究竟是什麼? 爲何倉儲服務沒發送ack就宕機了,RabbitMQ能夠自動感知到他宕機了,而後自動重發消息給其餘的倉儲服務實例呢?
這些東西背後的實現原理和底層細節,究竟是什麼?
大夥兒稍安勿躁,接下來,我們會經過一系列文章,仔細探究一下這背後的原理。
若有收穫,請幫忙轉發,您的鼓勵是做者最大的動力,謝謝!
一大波微服務、分佈式、高併發、高可用的原創系列文章正在路上
歡迎掃描下方二維碼,持續關注:
石杉的架構筆記(id:shishan100)
十餘年BAT架構經驗傾囊相授
推薦閱讀:
二、【雙11狂歡的背後】微服務註冊中心如何承載大型系統的千萬級訪問?
三、【性能優化之道】每秒上萬併發下的Spring Cloud參數優化實戰
六、大規模集羣下Hadoop NameNode如何承載每秒上千次的高併發訪問
七、【性能優化的祕密】Hadoop如何將TB級大文件的上傳性能優化上百倍
八、拜託,面試請不要再問我TCC分佈式事務的實現原理坑爹呀!
九、【坑爹呀!】最終一致性分佈式事務如何保障實際生產中99.99%高可用?
十一、【眼前一亮!】看Hadoop底層算法如何優雅的將大規模集羣性能提高10倍以上?
1六、億級流量系統架構之如何設計全鏈路99.99%高可用架構
1八、大白話聊聊Java併發面試問題之volatile究竟是什麼?
1九、大白話聊聊Java併發面試問題之Java 8如何優化CAS性能?
20、大白話聊聊Java併發面試問題之談談你對AQS的理解?
2一、大白話聊聊Java併發面試問題之公平鎖與非公平鎖是啥?
2二、大白話聊聊Java併發面試問題之微服務註冊中心的讀寫鎖優化
2三、互聯網公司的面試官是如何360°無死角考察候選人的?(上篇)
2四、互聯網公司面試官是如何360°無死角考察候選人的?(下篇)
2五、Java進階面試系列之一:哥們,大家的系統架構中爲何要引入消息中間件?
2六、【Java進階面試系列之二】:哥們,那你說說系統架構引入消息中間件有什麼缺點?
2七、【行走的Offer收割機】記一位朋友斬獲BAT技術專家Offer的面試經歷
2八、【Java進階面試系列之三】哥們,消息中間件在大家項目裏是如何落地的?
2九、【Java進階面試系列之四】扎心!線上服務宕機時,如何保證數據100%不丟失?
30、一次JVM FullGC的背後,竟隱藏着驚心動魄的線上生產事故!
3一、【高併發優化實踐】10倍請求壓力來襲,你的系統會被擊垮嗎?
3二、【Java進階面試系列之五】消息中間件集羣崩潰,如何保證百萬生產數據不丟失?
3三、億級流量系統架構之如何在上萬併發場景下設計可擴展架構(上)?
3四、億級流量系統架構之如何在上萬併發場景下設計可擴展架構(中)?
3五、億級流量系統架構之如何在上萬併發場景下設計可擴展架構(下)?
3七、億級流量系統架構之如何保證百億流量下的數據一致性(上)
3八、億級流量系統架構之如何保證百億流量下的數據一致性(中)?
3九、億級流量系統架構之如何保證百億流量下的數據一致性(下)?
做者:石杉的架構筆記 連接:juejin.im/post/5c263a… 來源:掘金 著做權歸做者全部,轉載請聯繫做者得到受權!