1. 程式人生 > >RabbitMQ的訊息可靠投遞 --上篇

RabbitMQ的訊息可靠投遞 --上篇

前言

上一節介紹了有關rabbitmq裡面常用了幾種命令,以及交換機的路由規則等,生產端以及消費端之間的虛擬碼來介紹了各種路由規則下的消費情況,從管控臺的設定,資料分析,瞭解到如何手動設定vhost下的交換機以及使用者,佇列等。這節開始就rabbitmq的高階特性進行詳細的介紹,比如TTL,死信佇列,限流,ACK以及失敗轉移等生產中常用到的特性。這裡貼上一篇分析rabbitmq原始碼的博文供讀者有餘力的話來自行修行,另外在CSDN另外一端有提及到rabbitmq專題的更詳細介紹,讀者也可前往深入研究。

訊息如何保障100%的投遞成功?

這裡投遞成功的意思是生產端生產訊息到broker,然後broker如何對生產端進行迴應接收到的過程,這裡就需要採取一定的訊息補償機制, 比如可以採用對訊息進行入庫狀態的標誌,如果成功返回應答訊息的進行狀態的變更,否則就對訊息進行輪詢的傳送處理,直到傳送訊息在努力嘗試的次數內得到最大的成功機率,這個還是需要看併發量,以及資料量,這個目前在筆者的專案中領導是要求達到併發量是200萬左右,這個就就需要用到訊息的可靠投遞的處理。
這裡是對訊息可靠處理的一種方案,首先訊息先入庫的操作然後再進行傳送的環節,step1是資料入庫,這裡的入庫包括業務型別入庫,以及傳送的訊息入庫,這裡沒有事務異常的持久化到磁碟後就進行step2傳送訊息到broker,step3是broker的應答過程,這裡可以通過定時任務來設定,訊息如果沒有在規定的時間內傳送回來應答就快速失敗。step4就開始非同步的監聽ACK,從這裡開始就對庫裡面的訊息的狀態進行處理,如果broker收到就更改訊息傳送狀態。而最重要的一步是step5-6,針對訊息的狀態進行重試投遞嘗試,這裡可能會出現一種情況是剛剛傳送訊息而broker沒來得及應答,這裡就開始嘗試重試傳送,所以這裡就需要對訊息超時的容忍做為過濾條件,再做step6就會比較合適,而step7是對重試的限制,留給人工處理的補償,來解決極端問題,比如網路問題,業務問題等等。
在這裡插入圖片描述


架構圖出來之後,這裡就需要在高併發場景下又如何處理?資料庫能否承受得這種頻繁的入庫操作?顯然,這樣的設計還是存在瓶頸。於是有了下面的架構方案來處理。
從下圖的這個方案,大致可以分為三個過程,第一個過程,藍色的方框,是處理訂單業務入庫的操作,這時候,有業務請求,先做持久化,記錄下ID,然後再發送訊息,傳送了訊息之後,消費端通過監聽mq叢集q1,處理訂單業務,處理完了之後就傳送訊息給mq叢集的佇列q2,提示訂單完成了,第二個過程是最上方的灰色做一個回撥的監聽,監聽到粉色的消費端消費的資訊,然後馬上做持久化入庫的操作,把業務訂單入庫,第三個過程是藍色的訂單服務傳送延時檢查訊息消費情況(可以設定5分鐘或者30分鐘,高峰時期可以根據實際資料量來自定義延時查詢時間)的請求到mq叢集q3,灰色的回撥服務監聽到延時的檢查請求訊息,馬上從資料庫查詢ID的訂單的消費狀態,如果沒有查詢到ID的訂單資訊或者該訂單消費失敗,就通過RPC的方式進行呼叫訂單服務
重新發送訊息,進行補償。這樣的三個過程就可以減少了資料庫的操作,訊息得到可靠的同時,效能得到提高
在這裡插入圖片描述

總結

在實際的生產裡面,是需要結合很多nosql資料庫進行處理,比如這裡的訂單服務的入庫操作可以使用redis叢集來處理,這樣的效率更高,而RPC的呼叫也有可能出現網路問題而導致請求重發失敗的情況,雖然這種情況還是極少數的,但是以防萬一,所以後面的還是需要人工補償來處理這個問題,比如這裡的延時申請,怎樣才能確保訊息已經消費入庫,如果訊息被消費端消費了,但是這個灰色的回撥入庫異常的情況?如果訊息沒有消費,需要補償的話,出現網路問題導致RPC請求失敗的情況?有興趣的讀者可以發表你的見解。