訊息中介軟體消費到的訊息處理失敗怎麼辦?
作者:愛釣魚的桌子哥
1、日趨流行的面試問法
現在網上很多面試題,主要是針對技術本身的提問,比如:你聊聊對Dubbo的理解?你說說分散式事務是什麼?
這些問題就好比中學考試的送分題,比如默寫古詩,你只要準備了,下點功夫,都沒啥問題。
所以這裡對技術本身的提問,其實就相當於送分題,主要是做一個基本的區分。你能回答出來,說明你至少平時還注意積累知識,不是一個混日子的工程師。
但是現在出去面試,尤其是一些大廠的面試越來越難了,從以前普通的技術知識本身,現在到了會考察你很多生產環境中的一些特殊狀況。
也就是說從以前的知識積累和背誦,到現在開始考察你的具體實踐和經驗積累。
比如現在可能很多面試官開始這麼問:你們專案裡用Dubbo時,有沒有遇到什麼技術問題?你們Dubbo服務的超時一般怎麼設定的?服務之間呼叫一般會遇到超時嗎?如果超時了會怎麼樣?
類似這樣的問題,都是在考察你對一個技術的實踐經驗,而這目前越來越成為了面試的重點。
所以本文將透過一道面試中的經典高頻問題:訊息中介軟體消費到的訊息處理失敗了怎麼辦?
藉助這道經典題目,來闡述一下這個問題。我們應該從哪些角度思考,才能做出滿分回答。
2、訊息中介軟體在生產系統中的使用
這是一個非常典型的生產環境的問題,很多公司都會在生產系統裡使用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出錯而已,不影響別人。
3、經典生產案例:早教盒子APP的發貨
接下來用一個經典的生產案例給大家說說MQ在生產的使用。
現在很多早教類的APP,都會提供早教盒子,什麼意思呢?
早教APP提供的核心服務就是三塊:
1、APP裡的早教影片課程
2、線上微信群的助教答疑指導
3、線下送你早教盒子,裡面有很多上課道具
這樣一個媽媽陪伴孩子上早教的過程可能是這樣的:
1、首先在APP裡看早教影片課程,孩子看著很感興趣。
2、接著媽媽從早教盒子裡取出來道具,陪孩子把影片裡的遊戲和任務都做一遍,讓孩子加深印象
3、最後每天媽媽會打卡,有助教會來給媽媽進行答疑。
所以說,假設現在我們要在一個早教APP裡購買一個早教課程,他的流程大致如下:
1、選擇購買早教課程
2、直接支付
3、建立訂單
4、給使用者增加課程許可權
5、通知倉庫準備發早教盒子
6、通知物流公司去倉庫取早教盒子進行配送。
我們來分析一下每個環節。首先你要是購買一個早教課程,那麼點選“購買”的按鈕之後,一般直接會跳入一個支付介面。
這個時候,你就可以直接選擇支付了。此時後臺系統一定會透過支付系統跟第三方支付系統進行通訊,比如說支付寶、微信之類的,然後等待支付完成。
一旦支付完成,就會在自己內部系統幹兩個事:
第一,給這個使用者id建立一個訂單;
第二,給這個使用者id增加看某個早教影片課程的許可權。
此時使用者其實在“我的訂單”介面就可以看到自己的訂單了,而且在“我的課程”介面,就可以開始看早教課程的影片了。
如果對上面過程不太理解的,再看看下面的圖,應該就清楚了:
但是現在問題主要在後面兩個步驟,現在你的訂單系統作為核心入口,他要通知倉庫系統去扣減一個早教盒子的庫存。
同時,還得準備好早教盒子的發貨(比如說提前打包裝箱,準備一些給快遞公司使用的發貨單之類的,需要帖子箱子上)。
然後通知第三方物流公司的系統,可以去自己的倉庫取早教盒子發貨了。
這兩個步驟需要涉及到對倉庫系統以及第三方物流公司系統的呼叫,那麼是採用訂單系統直接同步呼叫那兩個系統的方式嗎?
恐怕不妥,因為這裡最大的問題就是效能問題和可用性問題。
舉個例子,假如現在倉庫系統部署在其他地方,因為網路問題導致效能很差,訪問速度很慢,那麼是不是可能會導致使用者支付之後,等待了幾分鐘都看不到整個流程的完成?
或者要是說第三方物流公司的系統現在要是故障了,暫時無法訪問,那麼會不會導致使用者支付了之後,一直沒有給使用者發貨早教盒子?
所以說,在這裡就應該引入MQ,訂單系統在完成訂單的建立以及課程的分配之後,就可以傳送一個訊息到MQ,然後有一個專門的倉儲系統負責消費這個訊息,接著嘗試去呼叫獨立倉庫系統通知發貨,以及通知第三方物流系統去配送。
整個過程,如下圖所示:
這麼做有什麼好處呢?
好處是顯而易見的,假如現在獨立倉庫系統和第三方物流系統的訪問效能突然變得很差,大不了就是倉儲系統在後面慢慢的跟人家通訊等著人家處理完畢好了,對訂單系統是沒影響的。
對於訂單系統而言,建立訂單和分配課程都是速度很快的,然後傳送個訊息到MQ速度也很快。
這樣一來,使用者看到的就是一兩秒的時間支付就成功了,然後可以查到訂單,看到自己的課程,然後訂單的物流顯示的是“待配送”的狀態。
那麼如果獨立倉庫系統或者第三方物流系統故障了,導致倉儲系統消費到一條訂單訊息之後,嘗試進行發貨失敗,也就是對這條消費到的訊息處理失敗。這種情況,怎麼處理?
這就是本文最核心的地方了!!!
4、死信佇列的使用:處理失敗的訊息
一般生產環境中,如果你有豐富的架構設計經驗,都會在使用MQ的時候設計兩個佇列:一個是核心業務佇列,一個是死信佇列。
核心業務佇列,就是比如上面專門用來讓訂單系統傳送訂單訊息的,然後另外一個死信佇列就是用來處理異常情況的。
之所以我們這篇文章丟擲一個面試題,結果先長篇大論說一個生產實踐案例和業務場景,就是因為面試被問到這個問題時,必須要結合你自己的業務實踐經驗來說。
你需要先給面試官說有血有肉的業務系統場景,然後再結合這個場景回答他的問題,因為面試官想聽的就是你真實的實踐經驗。
比如說要是第三方物流系統故障了,此時無法請求,那麼倉儲系統每次消費到一條訂單訊息,嘗試通知發貨和配送,都會遇到對方的介面報錯。
此時倉儲系統就可以把這條訊息拒絕訪問,或者標誌位處理失敗!注意,這個步驟很重要。
一旦標誌這條訊息處理失敗了之後,MQ就會把這條訊息轉入提前設定好的一個死信佇列中。
然後你會看到的就是,在第三方物流系統故障期間,所有訂單訊息全部處理失敗,全部會轉入死信佇列。
然後你的倉儲系統得專門有一個後臺執行緒,監控第三方物流系統是否正常,能否請求的,不停的監視。
一旦發現對方恢復正常,這個後臺執行緒就從死信佇列消費出來處理失敗的訂單,重新執行發貨和配送的通知邏輯。
死信佇列的使用,其實就是MQ在生產實踐中非常重要的一環,也就是架構設計必須要考慮的。
整個過程,如下圖所示:
5、總結
最後再給各位朋友強調一下,如果面試被問到生產實踐類的問題,一定記住:結合有血有肉的業務系統和場景來闡述你的實踐經驗,以及在業務場景下,應該如何設計技術方案。
這樣你的回答,才能匹配上面試官內心深處最希望聽到的滿分答案!
·END·
程式設計師的成長之路
路雖遠,行則必至
本文原發於 同名微信公眾號「程式設計師的成長之路」,回覆「1024」你懂得,給個讚唄。
回覆 [ 520 ] 領取程式設計師最佳學習方式
回覆 [ 256 ] 檢視 Java 程式設計師成長規劃
往期精彩回顧
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69902700/viewspace-2645035/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 訊息中介軟體—RocketMQ訊息消費(三)(訊息消費重試)MQ
- 訊息中介軟體
- 訊息中介軟體客戶端消費控制實踐客戶端
- 事件訊息生產消費中介軟體-OSS.DataFlow事件
- mq要如何處理訊息丟失、重複消費?MQ
- 訊息中介軟體—RocketMQ訊息傳送MQ
- 使用訊息中介軟體時,如何保證訊息僅僅被消費一次?
- 訊息中介軟體rabbitMQMQ
- 中介軟體之訊息中介軟體-pulsar
- Kafka中消費者延遲處理訊息Kafka
- 訊息中介軟體選型
- 訊息中介軟體之ActiveMQMQ
- 分散式訊息中介軟體分散式
- CRM中介軟體裡parent not ok的錯誤訊息如何處理
- 淺談訊息佇列及常見的訊息中介軟體佇列
- PHP 訊息中介軟體 工具庫PHP
- 解析訊息中介軟體之RabbitMQMQ
- 訊息中介軟體 — RocketMQ簡介MQ
- 訊息中介軟體 — 使用場景
- 輕量訊息中介軟體ZeroMQMQ
- 實際業務處理 Kafka 訊息丟失、重複消費和順序消費的問題Kafka
- Kafka、RabbitMQ、RocketMQ訊息中介軟體的對比 —— 訊息傳送效能KafkaMQ
- 訊息佇列——數十萬級訊息的消費方案佇列
- 訊息中介軟體—RocketMQ的RPC通訊(一)MQRPC
- kafka消費者消費訊息的流程Kafka
- 如何處理RabbitMQ 訊息堆積和訊息丟失問題MQ
- 從通訊開始聊聊訊息中介軟體
- Spring Cloud Stream如何處理訊息重複消費?SpringCloud
- 高併發場景下,如何保證生產者投遞到訊息中介軟體的訊息不丟失?
- 訊息中介軟體Notify和MetaQ-阿里中介軟體阿里
- 訊息佇列-如何保證訊息的不被重複消費(如何保證訊息消費的冪等性)佇列
- 訊息中介軟體—Kafka 的設計思想Kafka
- 訊息中介軟體的應用場景
- 常見訊息中介軟體之ActiveMQMQ
- 常見訊息中介軟體之RocketMQMQ
- 深入訊息中介軟體選型分析
- 訊息中介軟體與JMS標準
- [分散式][訊息中介軟體]訊息中介軟體如何實現每秒幾十萬的高併發寫入分散式