您好,登錄后才能下訂單哦!
現在網上很多面試題,主要是針對技術本身的提問,比如:你聊聊對Dubbo的理解?你說說分布式事務是什么?
這些問題就好比中學考試的送分題,比如默寫古詩,你只要準備了,下點功夫,都沒啥問題。
所以這里對技術本身的提問,其實就相當于送分題,主要是做一個基本的區分。你能回答出來,說明你至少平時還注意積累知識,不是一個混日子的工程師。
但是現在出去面試,尤其是一些大廠的面試越來越難了,從以前普通的技術知識本身,現在到了會考察你很多生產環境中的一些特殊狀況。
也就是說從以前的知識積累和背誦,到現在開始考察你的具體實踐和經驗積累。
比如現在可能很多面試官開始這么問:你們項目里用Dubbo時,有沒有遇到什么技術問題?你們Dubbo服務的超時一般怎么設置的?服務之間調用一般會遇到超時嗎?如果超時了會怎么樣?
類似這樣的問題,都是在考察你對一個技術的實踐經驗,而這目前越來越成為了面試的重點。
所以本文將通過一道面試中的經典高頻問題:消息中間件消費到的消息處理失敗了怎么辦?
借助這道經典題目,來闡述一下這個問題。我們應該從哪些角度思考,才能做出滿分回答。
這是一個非常典型的生產環境的問題,很多公司都會在生產系統里使用MQ,即消息隊列,或者消息中間件。
也就是說,一個系統跟另外一個系統之間進行通信的時候,假如系統A希望發送一個消息給系統B,讓他去處理。
但是系統A不關注系統B到底怎么處理或者有沒有處理好,所以系統A把消息發送給MQ,然后就不管這條消息的“死活”了,接著系統B從MQ里消費出來處理即可。
至于怎么處理,是否處理完畢,什么時候處理,都是系統B的事兒,與系統A無關。
上述過程,可以通過下圖看的很清晰:
這樣的一種通信方式,就是所謂的“異步”通信方式
對于系統A來說,只要把消息發給MQ,然后系統B就會異步的去進行處理了,系統A不需要“同步”的等待系統B處理完。
這樣的好處是什么呢?
兩個字:解耦
系統A要跟系統B通信,但是他不需要關注系統B如何處理的一些細節。我們來舉幾個例子說明:
比如,A不需要關注B什么時候處理完,這樣假如系統B處理一個消息要耗費10分鐘也不關系統A的事兒。
否則,系統A直接調用系統B的接口,系統B一下子處理了10分鐘怎么辦?難不成系統A也阻塞等待10分鐘?
再比如,系統A不需要關注系統B處理成功與否,即使系統B處理失敗了,也是系統B自己去考慮這個場景和重新嘗試處理。
否則如果系統調用系統B的接口,萬一處理失敗了報錯了,系統A受到一個調用異常該怎么處理?
還有,系統A不需要關注系統B是否存活。萬一要是系統B掛掉了,系統A通過MQ來通信也不需要管系統B的“死活”,系統B自己恢復了之后就可以從MQ消費消息再次處理即可。
否則系統A直接調用系統B的接口,萬一系統B掛了,難道系統A還要把消息暫存到數據庫?等待系統B恢復了再給他發過去嗎?
這就是通過MQ進行異步通信,讓兩個系統解耦之后的好處,可以大幅度提升整個大系統的容錯性,增加系統的彈性,而不是處處耦合,一個系統出錯連帶導致其他系統全部出錯。
解耦之后,即使出錯也只是大系統中的一個系統B出錯而已,不影響別人。
接下來用一個經典的生產案例給大家說說MQ在生產的使用。
現在很多早教類的APP,都會提供早教盒子,什么意思呢?
早教APP提供的核心服務就是三塊:
這樣一個媽媽陪伴孩子上早教的過程可能是這樣的:
所以說,假設現在我們要在一個早教APP里購買一個早教課程,他的流程大致如下:
我們來分析一下每個環節。首先你要是購買一個早教課程,那么點擊“購買”的按鈕之后,一般直接會跳入一個支付界面。
這個時候,你就可以直接選擇支付了。此時后臺系統一定會通過支付系統跟第三方支付系統進行通信,比如說支付寶、微信之類的,然后等待支付完成。
一旦支付完成,就會在自己內部系統干兩個事:
此時用戶其實在“我的訂單”界面就可以看到自己的訂單了,而且在“我的課程”界面,就可以開始看早教課程的視頻了。
如果對上面過程不太理解的,再看看下面的圖,應該就清楚了:
但是現在問題主要在后面兩個步驟,現在你的訂單系統作為核心入口,他要通知倉庫系統去扣減一個早教盒子的庫存。
同時,還得準備好早教盒子的發貨(比如說提前打包裝箱,準備一些給快遞公司使用的發貨單之類的,需要帖子箱子上)。
然后通知第三方物流公司的系統,可以去自己的倉庫取早教盒子發貨了。
這兩個步驟需要涉及到對倉庫系統以及第三方物流公司系統的調用,那么是采用訂單系統直接同步調用那兩個系統的方式嗎?
恐怕不妥,因為這里最大的問題就是性能問題和可用性問題。
舉個例子,假如現在倉庫系統部署在其他地方,因為網絡問題導致性能很差,訪問速度很慢,那么是不是可能會導致用戶支付之后,等待了幾分鐘都看不到整個流程的完成?
或者要是說第三方物流公司的系統現在要是故障了,暫時無法訪問,那么會不會導致用戶支付了之后,一直沒有給用戶發貨早教盒子?
所以說,在這里就應該引入MQ,訂單系統在完成訂單的創建以及課程的分配之后,就可以發送一個消息到MQ,然后有一個專門的倉儲系統負責消費這個消息,接著嘗試去調用獨立倉庫系統通知發貨,以及通知第三方物流系統去配送。
整個過程,如下圖所示:
這么做有什么好處呢?
好處是顯而易見的,假如現在獨立倉庫系統和第三方物流系統的訪問性能突然變得很差,大不了就是倉儲系統在后面慢慢的跟人家通信等著人家處理完畢好了,對訂單系統是沒影響的。
對于訂單系統而言,創建訂單和分配課程都是速度很快的,然后發送個消息到MQ速度也很快。
這樣一來,用戶看到的就是一兩秒的時間支付就成功了,然后可以查到訂單,看到自己的課程,然后訂單的物流顯示的是“待配送”的狀態。
那么如果獨立倉庫系統或者第三方物流系統故障了,導致倉儲系統消費到一條訂單消息之后,嘗試進行發貨失敗,也就是對這條消費到的消息處理失敗。這種情況,怎么處理?
這就是本文最核心的地方了!!!
一般生產環境中,如果你有豐富的架構設計經驗,都會在使用MQ的時候設計兩個隊列:一個是核心業務隊列,一個是死信隊列。
核心業務隊列,就是比如上面專門用來讓訂單系統發送訂單消息的,然后另外一個死信隊列就是用來處理異常情況的。
之所以我們這篇文章拋出一個面試題,結果先長篇大論說一個生產實踐案例和業務場景,就是因為面試被問到這個問題時,必須要結合你自己的業務實踐經驗來說。
你需要先給面試官說有血有肉的業務系統場景,然后再結合這個場景回答他的問題,因為面試官想聽的就是你真實的實踐經驗。
比如說要是第三方物流系統故障了,此時無法請求,那么倉儲系統每次消費到一條訂單消息,嘗試通知發貨和配送,都會遇到對方的接口報錯。
此時倉儲系統就可以把這條消息拒絕訪問,或者標志位處理失敗!注意,這個步驟很重要。
一旦標志這條消息處理失敗了之后,MQ就會把這條消息轉入提前設置好的一個死信隊列中。
然后你會看到的就是,在第三方物流系統故障期間,所有訂單消息全部處理失敗,全部會轉入死信隊列。
然后你的倉儲系統得專門有一個后臺線程,監控第三方物流系統是否正常,能否請求的,不停的監視。
一旦發現對方恢復正常,這個后臺線程就從死信隊列消費出來處理失敗的訂單,重新執行發貨和配送的通知邏輯。
死信隊列的使用,其實就是MQ在生產實踐中非常重要的一環,也就是架構設計必須要考慮的。
整個過程,如下圖所示:
最后再給各位朋友強調一下,如果面試被問到生產實踐類的問題,一定記住:結合有血有肉的業務系統和場景來闡述你的實踐經驗,以及在業務場景下,應該如何設計技術方案。
這樣你的回答,才能匹配上面試官內心深處最希望聽到的滿分答案!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。