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