訂單隊列架構(gòu)思想

前序

一般的訂單流程

思考瓶頸點

訂單隊列

第一種訂單隊列流程圖:

第二種訂單隊列流程圖:

總結(jié)

實現(xiàn)隊列的選擇

解答

第二種隊列的 Go 版本例子代碼

前序

本文所要分享的思路就是電商應(yīng)用中常用的訂單隊列。

一般的訂單流程

電商應(yīng)用中,簡單直觀的用戶從下單到付款,最終完成整個流程的步驟可以用下圖表示:

其中,訂單信息持久化,就是存儲數(shù)據(jù)到數(shù)據(jù)庫中。而最終客戶端完成支付后的更新訂單狀態(tài)的操作是由第三方支付平臺進(jìn)行回調(diào)設(shè)置好的回調(diào)鏈接?NotifyUrl,來進(jìn)行的。

補(bǔ)全訂單狀態(tài)的更新流程,如下圖表示:

思考瓶頸點

服務(wù)端的直接瓶頸點,首先要考慮?TPS。去除細(xì)分點,我們主要看訂單信息持久化瓶頸點。

在高并發(fā)業(yè)務(wù)場景中,例如?秒殺、優(yōu)惠價搶購等。短時間內(nèi)的下單請求數(shù)會很多,如果訂單信息持久化?部分,不做優(yōu)化,而是直接對數(shù)據(jù)庫層進(jìn)行頻繁的讀寫操作,數(shù)據(jù)庫會承受不了,容易成為第一個垮掉的服務(wù),比如下圖的所示的常規(guī)寫單流程:

可以看到,每持久化一個訂單信息,一般要經(jīng)歷網(wǎng)絡(luò)連接操作(鏈接數(shù)據(jù)庫),以及多個?I/O?操作。

得益于連接池技術(shù),我們可以在鏈接數(shù)據(jù)庫的時候,不用每次都重新發(fā)起一次完整的HTTP請求,而可以直接從池中獲取已打開了的連接句柄,而直接使用,這點和線程池的原理差不多。

此外,我們還可以在上面的流程中加入更多的優(yōu)化,例如對于一些需要讀取的信息,可以事先存置到內(nèi)存緩存層,并加于更新維護(hù),這樣在使用的時候,可以快速讀取。

即使我們都具備了上述的一些優(yōu)化手段,但是對于寫操作的I/O阻塞耗時,在高并發(fā)請求的時候,依然容易導(dǎo)致數(shù)據(jù)庫承受不住,容易出現(xiàn)鏈接多開異常,操作超時等問題。

在該層進(jìn)行優(yōu)化的操作,除了上面談到的之外,還有下面一些手段:

數(shù)據(jù)庫集群,采用讀寫分離,減少寫時壓力

分庫,不同業(yè)務(wù)的表放到不同的數(shù)據(jù)庫,會引入分布式事務(wù)問題

采用隊列模型削峰

每種方式有各自的特點,因為本文談的是訂單隊列的架構(gòu)思想,所以下面我們來看下如何在訂單系統(tǒng)中引入訂單隊列。

訂單隊列

網(wǎng)上有不少文章談到訂單隊列的做法,大部分都漏了說明請求與響應(yīng)的一致性問題。

第一種訂單隊列流程圖:

上圖是大多文章提到的隊列模型,有兩個沒有解析的問題:

如果訂單存在第三方支付情況,① 和 ② 的一致性如何保證,比如其中一處處理失??;

如果訂單存在第三方支付情況,① 完成了支付,且三方支付平臺回調(diào)了notifyUrl,而此時 ② 還在排隊等待處理,這種情況又如何處理。

首先,要肯定的是,上面的訂單流程圖是沒有問題的。它有下面的優(yōu)缺點,所提到的兩個問題也是有解決方案的。

優(yōu)點:

用戶無需等待訂單持久化處理,而能直接獲得響應(yīng),實現(xiàn)快速下單

持久化處理,采用排隊的先來先處理,不會像上面談到的高并發(fā)請求一起沖擊數(shù)據(jù)庫層面的情況。

可變性強(qiáng),搭配中間件的組合性強(qiáng)。

缺點:

多訂單入隊時,② 步驟的處理速度跟不上。從而導(dǎo)致第二點問題。

實現(xiàn)較復(fù)雜

上面談及的問題點,我后面都會給出解決方案。下面我們來看下另外一種訂單隊列流程圖。

第二種訂單隊列流程圖:

第二種訂單隊列的設(shè)計模型,注意它的同步等待持久化處理的結(jié)果,解決了持久化與響應(yīng)的一致性問題,但是有個嚴(yán)重的耗時等待問題,它的優(yōu)缺點如下:

優(yōu)點:

持久化與響應(yīng)的強(qiáng)一致性。

持久化處理,采用排隊的先來先處理,不會像上面談到的高并發(fā)請求一起沖擊數(shù)據(jù)庫層面的情況。

實現(xiàn)簡單

缺點:

多訂單入隊時,持久化單元處理速度跟不上,造成客戶端同步等待響應(yīng)。

這類訂單隊列,我下面會放出?Golang?實現(xiàn)的版本代碼。

總結(jié)

對比上面兩種常見的訂單模型,如果從用戶體驗的角度去優(yōu)先考慮,第一種不需要用戶等待持久化處理結(jié)果的是明顯優(yōu)于第二種的。如果技術(shù)團(tuán)隊完善,且技術(shù)過硬,也應(yīng)該考慮第一種的實現(xiàn)方式。

如果僅僅想要達(dá)到寧愿用戶等待到超時也不愿意存儲層服務(wù)被沖垮,那么有限考慮第二種。

實現(xiàn)隊列的選擇

在這里,我們進(jìn)一步細(xì)分一下,實現(xiàn)隊列模塊的功能有哪些選擇。

相信很多后端開發(fā)經(jīng)驗比較老道的同志已經(jīng)想到了,使用現(xiàn)有的中間件,比如知名的?Redis、RocketMQ,以及?Kafka?等,它們都是一種選擇。

此外地,我們還可以直接編寫代碼,在當(dāng)前的服務(wù)系統(tǒng)中實現(xiàn)一個消息隊列來達(dá)到目的,下面我用圖來分類下隊列類型。

不同的隊列實現(xiàn)方式,能直接導(dǎo)致不同的功能,也有不同的優(yōu)缺點:

一級緩存優(yōu)點:

一級緩存,最快。無需鏈接,直接從內(nèi)存層獲??;

如果不考慮持久化和集群,那么它實現(xiàn)簡單。

一級緩存缺點:

如果考慮持久化和集群,那么它實現(xiàn)比較復(fù)雜。

不考慮持久化情況下,如果服務(wù)器斷電或其它原因?qū)е路?wù)中斷,那么排隊中的訂單信息將丟失

中間件的優(yōu)點:

軟件成熟,一般出名的消息中間件都是經(jīng)過實踐使用的,文檔豐富;

支持多種持久化的策略,比如 Redis 有增量持久化,能最大程度減少因不可預(yù)料的崩潰導(dǎo)致訂單信息丟失;

支持集群,主從同步,這對于分布式系統(tǒng)來說,是必不可少的要求。

中間件的缺點:

分布式部署時,需要建立鏈接通訊,導(dǎo)致讀寫操作需要走網(wǎng)絡(luò)通訊。

解答

回到第一種訂單模型中:

問題1:

如果訂單存在第三方支付情況,① 和 ② 的一致性如何保證?

首先我們看下,不一致性的時候,會產(chǎn)生什么結(jié)果:

① 失敗,用戶因為網(wǎng)絡(luò)原因或返回其它頁面,不能獲取結(jié)果。而 ② 成功,那么最終該訂單的狀態(tài)是待支付。用戶進(jìn)入到個人訂單中心完成訂單支付即可;

① 和 ② 都失敗,那么下單失?。?/p>

① 成功,② 失敗,此時用戶在響應(yīng)頁面完成了支付動作,用戶查看訂單信息為空白。

上述的情況,明顯地,只有 3 是需要恢復(fù)訂單信息的,應(yīng)對的方案有:

當(dāng)服務(wù)端支付回調(diào)接口被第三方支付平臺訪問時,無法找到對應(yīng)的訂單信息。那么先將這類支付了卻沒訂單信息的數(shù)據(jù)存儲起來先,比如存儲到表A。同時啟動一個定時任務(wù)B專門遍歷表A,然后去訂單列表尋找是否已經(jīng)有了對應(yīng)的訂單信息,有則更新,沒則繼續(xù),或跟隨制定的檢測策略走。

當(dāng) ② 是由于服務(wù)端的`非崩潰性原因而導(dǎo)致失敗時:

失敗的時候同時將原始訂單數(shù)據(jù)重新插入到隊列頭部,等待下一次的重新持久化處理。

當(dāng) ② 因服務(wù)端的`崩潰性原因而導(dǎo)致失敗時:

定時任務(wù)B在進(jìn)行了多次檢測無果后,那么根據(jù)第三方支付平臺在回調(diào)時候傳遞過來的訂單附屬信息對訂單進(jìn)行恢復(fù)。

整個過程訂單恢復(fù)的過程,用戶查看訂單信息為空白。

定時任務(wù)B?所在服務(wù)最好和回調(diào)鏈接?notifyUrl?所在的接口服務(wù)一致,這樣能保證當(dāng) B 掛掉的時候,回調(diào)服務(wù)也跟隨掛掉,然后第三方支付平臺在調(diào)用回調(diào)失敗的情況下,他們會有重試邏輯,依賴這個,在回調(diào)服務(wù)重啟時,可以完成訂單信息恢復(fù)。

問題2:

如果訂單存在第三方支付情況,① 完成了支付,且三方支付平臺回調(diào)了 notifyUrl,而此時 ② 還在排隊等待處理,這種情況又如何處理?

應(yīng)對的方案參考?問題1?的?定時任務(wù)B?檢測修改機(jī)制,或者是另加一個定時任務(wù)主動發(fā)起查詢的機(jī)制。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容