1. 程式人生 > >電商訂單技術方案梳理

電商訂單技術方案梳理

對於電商系統來說,下訂單的服務是相當重要的。下訂單服務的好與壞甚至影響到使用者的體驗,以及後續是否再次購買等行為。近期對於我們系統的下訂單業務進行梳理,總結如下。

一般的下單流程

 1. 使用者挑選相應的商品放入購物車;
 2. 點選購買,進入訂單詳情頁(這一頁也可以通過購物車頁,點選商品之後進入);
 3. 點選下單,生成相應的訂單;
 4. 點選支付進入支付環節;

我們主要分析第3步:

前端請求提交了相應的訂單詳情頁資料進來;
後臺服務接收請求,在各情況下所使用技術策略不會是一成不變的,而是為了應對各種場景而採用了不同的實現方案,下面我們就來分析兩種場景。一種場景是普通的下單;另一種場景是秒殺。

普通的下單:

前端請求提交了訂單詳情頁的資料至訂單提交服務,後臺服務接收請求,後臺服務的一般處理步驟:

 1. 校驗資料的正確性、合法性,這涉及幾個方面:庫存、商品價格檢查、使用促銷規則、商品售賣區域校驗等;
 2. 資料模型的轉化,將商品模型轉化為訂單模型,主要包括訂單、訂單詳情兩部分;
 3. 訂單額度計算;
 4. 訂單資料的寫入資料庫;
 5. 訂單寫入成功訊息投遞;
 6. 返回前端呼叫;

在這6步中,其中只有第4步是需要直接操作資料庫(一般情況下都是mysql資料庫)的。為什麼這麼說呢?原因是其他幾步要麼是記憶體計算,要麼需要的資料是可以進行快取的。比如庫存,它是可以通過快取系統進行快取,由於出現快取資料與db不一致,才會出現部分電商公司說在什麼什麼情況下,他們的商品超賣了等情況。

那麼在高併發的場景下,對於普通的下單方案是不可行的。原因是資料的寫入會出現瓶頸。為了解決這個問題,需要引入另外的方案,即秒殺的訂單方案。

秒殺下單流程

剛才我們分析了普通的下單流程,只要能夠解決其在高併發的場景下的寫入瓶頸,就可以應對秒殺場景(這裡暫且不討論服務的降級)。對於秒殺下單它的流程與普通下單一樣,只需要解決第4步的寫入效能瓶頸即可。對於高併發,它的解決思路是分而治之。對於這個分而治之的解決方案有千萬種,這裡只介紹一種,即使用訊息佇列來抗高併發的寫入,即經常說的使用“訊息佇列削峰”。簡單來說,就是在第4步訂單不直接寫入資料庫,而是寫入訊息佇列。而後通過訊息佇列的客戶端拉取訂單再慢慢寫入資料庫,從而解決資料庫的寫入瓶頸。在我們的業務系統中,可以使用redis作為這個消算佇列,進行訂單的寫入,訂單資料寫入訊息佇列步驟如下:

 1. 呼叫訂單id生成服務,生成唯一id,存入訂單模型;
 2. 呼叫訂單詳情id生成服務,生成唯一id,存入訂單詳情;
 3. 訂單及訂單詳情序列化寫入redis訂單kv結構中,k為訂單id;v為訂單資料;
 4. 使用者與訂單id的關係反表寫入redis kv結構,k為使用者id;v為訂單id;為了解決使用者的訂單列表查詢無法查到最新訂單的問題;
 5. 訂單id寫入redis列表,即訊息佇列;用於訊息的傳送;
 6. 寫入完成;

使用id生成器,為了解決訂單的唯一性與分庫等操作,另外還有後續的操作api是依賴該訂單的id屬性,對於id生成器的解決方案也有n多種,具體可能看訂單id生成服務

對於在後臺執行的訊息佇列客戶端,它的主要業務邏輯:

 1. 拉取佇列;
 2. 通過鍵值查詢獲取訂單詳細資訊;
 3. 寫入訂單資料到資料庫;
 4. 刪除redis中訂單鍵值;
 5. 刪除redis中使用者與訂單鍵值;
 6. 迴圈第一步.