分享一個訂單推送消息的設計案例

首先簡單的描述一下業務場景。這是一個訂單消息推送功能,當有訂單進入後,系統會給有關人員及時推送訂單的信息,內容包括訂單金額,訂單時間和當天的訂單合計數。系統中訂單生成後,後續的相關業務處理也比較多,並且要及時完成第三方支付平臺(微信,支付寶,銀聯)的響應請求,以免接受重複的成單請求。還有因為業務的特殊性(一筆訂單金額都在萬元左右),所以不會有大量訂單壓力,可以不考慮集群。


經過簡單溝通和思考後,出了第一版設計:

1:訂單的處理模塊和後續業務處理分離,採用異步調用(簡單的話就是線程處理,也可以採用mq)。防止處理時間過長,導致第三方支付的多次回調。也要設計冪等性功能,防止重複回調。

2:消息推送採用企業微信推送(目前微信的使用率高於郵件和短信)。

測試人員做了一次併發測試,出現了一個問題。如下圖所示,訂單A和訂單B同時進入系統,消息推送兩條,兩條消息中當天訂單數均顯示單數是2單。正常應該是第一個消息是1單,第二個消息顯示2單。分享一個訂單推送消息的設計案例

原因分析:

訂單A進入訂單表後,接著異步調用後續業務處理模塊,最後到信息推送模塊之前,這時訂單B進來了,插入了訂單表。第一條消息推送按此時數據庫中的訂單A和訂單B進行了合計,當天成單數結果顯示成了2單。這時輪到第二個訂單的消息推送時,也是數據庫中的訂單A和訂單B,結果也顯示2單。

解決方案:

方案1:每個訂單設計業務序號(自增字段),訂單生成模塊調用後續處理時傳入當前訂單的業務序號。推送消息當天訂單數按照小於當前訂單的業務序號進行單數合計。(集群的情況下,要考慮業務序列號的生成算法,就不能是單一的自增了,比如可以用redis,方案很多)

方案2:鑑於本系統的高併發的壓力不大,可以採用時間戳的方式。直接利用訂單表的生成時間的字段。(精確到秒,當然鑑於不同的系統的併發性可以精確到毫秒級別)。下圖是方案2的示例

分享一個訂單推送消息的設計案例

上線後,有進行了大量的測試,報單的單數計算每問題了,但是偶爾會出現消息發不出去的情況。經過調查,微信發消息接口有時會返回調用失敗的情況。為了保證消息的可靠性,提出了以下兩種方案:

方案1:簡單的重複調用三次。弊端是,短時間內的重複調用可能都會失敗(微信接口系統繁忙的時候)。

方案2:利用MQ。先將消息插入MQ,之後MQ的消費者進行消息接口的調用,調用成功則消費成功,如果消費失敗,按照不同的頻率重複調用,每次的調用的間隔時間逐漸延長,總共調用十次。(一個小時之內)。

目前系統運行了半年時間,還沒出現什麼問題。當然設計方案有很多,歡迎大家多提寶貴意見。


分享到:


相關文章: