消息隊列:第四章:延遲檢查隊列

分布式事務(wù)的異步通信問題

使用分布式事務(wù)異步通信的結(jié)構(gòu),一個很大的問題就是不確定性。一個消息發(fā)送過去了,不管結(jié)果如何發(fā)送端都不會原地等待接收端。直到接收端再推送回來回執(zhí)消息,發(fā)送端才直到結(jié)果。但是也有可能發(fā)送端消息發(fā)送后,石沉大海,杳無音信。這時候就需要一種機制能夠?qū)@種不確定性進行補充。

比如你給有很多筆友,平時寫信一去一回,但是有時候會遇到遲遲沒有回信的情況。那么針對這種偶爾出現(xiàn)的情況,你可以選擇兩種策略。一種方案是你發(fā)信的時候用定個鬧鐘,設(shè)定1天以后去問一下對方收沒收到信。另一種方案就是每天夜里定個時間查看一下所有發(fā)過信但是已經(jīng)一天沒收到回復(fù)的信。然后挨個打個電話問一下。

第一種策略就是實現(xiàn)起來就是延遲隊列,第二種策略就是定時輪詢掃描。

二者的區(qū)別是延遲隊列更加精準,但是如果周期太長,任務(wù)留在延遲隊列中時間的就會非常長,會把隊列變得冗長。比如用戶幾天后待辦提醒,生日提醒。

那么如果遇到這種長周期的事件,而且并不需要精確到分秒級的事件,可以利用定時掃描來實現(xiàn),尤其是比較消耗性能的大范圍掃描,可以安排到夜間執(zhí)行。

 
延遲隊列
什么是延遲隊列?

一般的隊列,消息一旦入隊了之后就會被消費者馬上消費。

延遲隊列就是進入該隊列的消息會被延遲消費。
可以做什么?

1、延遲消費。比如:

    用戶生成訂單之后,需要過一段時間校驗訂單的支付狀態(tài),如果訂單仍未支付則需要及時地關(guān)閉訂單。
    用戶注冊成功之后,需要過一段時間比如一周后校驗用戶的使用情況,如果發(fā)現(xiàn)用戶活躍度較低,則發(fā)送郵件或者短信來提醒用戶使用。

2、延遲重試。比如消費者從隊列里消費消息時失敗了,但是想要延遲一段時間后自動重試。

如果不使用延遲隊列,那么我們只能通過一個輪詢掃描程序去完成。這種方案既不優(yōu)雅,也不方便做成統(tǒng)一的服務(wù)便于開發(fā)人員使用。但是使用延遲隊列的話,我們就可以輕而易舉地完成。
 應(yīng)用場景

當用戶選擇支付后,通常來說用戶都會在支付寶正常支付,支付寶轉(zhuǎn)賬成功后,通過后臺異步發(fā)送成功的請求到電商支付模塊。

但是如果用戶點擊支付后,支付模塊可能會長時間沒有收到支付寶的支付成功通知。這種情況會‘有兩種可能性,一種是用戶在彈出支付寶付款界面時沒有繼續(xù)支付,另一種就是用戶支付成功了,但是因為網(wǎng)絡(luò)等各種問題,支付模塊沒有收到通知。

如果是上述第二種可能性,對于用戶來說體驗是非常糟糕的,甚至會懷疑平臺的誠信。

所以為了盡可能避免第二種情況,在用戶點擊支付后一段時間后,不管用戶是否付款,都要去主動詢問支付寶,該筆單據(jù)是否付款。

 

圖中紫線部分,就是支付模塊一旦幫助用戶重定向到支付寶后,就要每隔一段時間詢問支付寶用戶是否支付成功,直到收到支付寶的回復(fù),或者超過了詢問次數(shù)。

 
2  實現(xiàn)思路

   首先,需要知道如何主動查詢支付寶中某筆交易的狀態(tài)。

支付寶查詢接口文檔:https://docs.open.alipay.com/api_1/alipay.trade.query

   其次,利用延遲隊列反復(fù)調(diào)用。