如何設計一個電商平臺積分兌換系統?

公衆號:狸貓技術窩

做者:原子彈大俠,高級技術專家面試


目錄
express

1.拉開差距的一類面試題
性能優化

2.業務需求描述 微信

3.對業務流程的思考 架構

4.物流配送進度查詢,考慮到了嗎? 併發

5.事務的保證 異步

6.消息中間件的引入 分佈式

7.重試機制的引入 高併發

8.引入冪等性機制 post

9.對這類面試題的總結


一、拉開差距的一類面試題

如今面試常常會遇到一類問題,面試官讓你現場設計出某個業務場景下的一個系統,這個系統每每在業務或者技術上有必定難度,主要考察的是你多年積澱下來的系統設計的能力以及技術思惟的能力。

相似的這類系統設計題目不少,好比:

  • 請你設計一個秒殺系統

  • 請你設計一個支撐百萬用戶的IM消息系統

  • 請你設計一個微信紅包系統

  • 請你設計一個電商平臺積分兌換系統

這些題目自己都是開放式命題,沒有固定答案。遇到這種問題,必定不要慌,關鍵是在現場要思路清楚,有理有據,慢慢分析。

本文就其中一個問題:設計一個電商平臺的積分兌換系統,來詳細闡述一下。文中會詳細指出在系統設計的時候要考慮哪些要點,給你們展現出來這類問題思考的一個過程。


二、業務需求的描述

假設面試官如今給出來對於這個電商平臺的積分兌換系統的相關需求以下:

  1. 用戶在電商平臺裏平時經過購買商品、曬單評論能夠有不斷的積累積分

  2. 積累到足夠的積分後,就能夠在電商平臺的積分兌換頁面中,選擇使用本身的積分來兌換一些禮品

需求其實就這麼簡單,那麼面試官說了,針對這個業務場景給出你對這個機制實現的思考過程以及這裏要注意的一些地方。


三、對業務流程的思考

如何思考?首先,用戶不停的購買商品以及曬單評論,會不斷的獲取積分,那麼是否是須要一張積分表,專門用來存儲每一個用戶的積分呢?

沒錯,這個表是必定須要的,能夠現場給出下述的表結構。

積分表

  • id(自增id主鍵)

  • user_id(用戶id)

  • credit(積分)

繼續來看,假設在積分兌換頁面,用戶選擇用本身的20000積分兌換一瓶洗髮水,後臺的邏輯應該如何設計呢?

這個也是必須得現場給出一個思考過程的,這個其實看起來簡單,可是不少年紀較輕,經驗不足的朋友,可能無法快速思考出來。

首先你要用20000積分去進行兌換,那麼必定是必需要在積分表裏扣減掉這20000積分的吧?因此在流程設計中,首先就得有一個20000積分扣減的過程。

其次,你用這20000積分兌換了什麼東西呢?

因此你是否是還須要一張單獨的表,叫作積分兌換記錄表,記錄下來你這個用戶本次用多少積分兌換了一件什麼商品?

這個積分兌換記錄表的結構以下所示,你是否是須要在下面的那個表裏插入一條記錄,說這個用戶本次用多少積分兌換了哪一個商品?

積分兌換表

  • id(自增id主鍵)

  • user_id(用戶id)

  • exchanged_credit(用於兌換的積分)

  • product_id(兌換的商品id)

最後,光是插入上述那條積分兌換記錄是不夠的,你必須得調用倉儲業務模塊的接口,通知倉儲業務模塊新增一條發貨申請,並且應該是積分兌換對應的發貨申請,這樣保證倉庫能夠準備對應的商品進行發貨。

這個發貨申請大體對應以下的表結構:

發貨申請表

  • id(自增id主鍵)

  • type(發貨類型,1:購買,2:積分兌換)

  • credit_exchange_id(積分兌換表的id)

  • product_id(要發貨的商品id)

其實這裏的發貨申請表簡化了不少,按理說還得有發貨商品的數量等等字段,可是這裏能夠簡化處理也沒事,畢竟是面試現場。

簡單畫出來這個流程大體以下所示。


四、物流配送進度查詢,考慮到了嗎?

若是把上面那整個業務流程給面試官說了,就完事了嗎?

固然不是!

你能夠站在用戶的角度考慮一下,你是否是確定還須要查看積分兌換的記錄?這個在積分兌換表裏能夠查看到你用多少積分兌換了什麼商品。

可是你兌換商品的物流配送進度,能查看到嗎?不能。因此你應該在業務流程裏再考慮進去對應的物流配送的邏輯。

一般來講一個基本的邏輯,就是在生產發貨申請單的時候,須要調用第三方物流公司的接口申請一個物流單,這樣倉庫管理員打包準備好商品,坐等物流公司商品收快遞就能夠了。

物流公司會根據物流單去進行配送,這個配送地址固然是用戶本身在電商平臺選擇的本身的某個地址。

此時發貨申請單的表結構是否是以下所示?

發貨申請表

  • id(自增id主鍵)

  • type(發貨類型,1:購買,2:積分兌換)

  • credit_exchange_id(積分兌換表的id)

  • product_id(要發貨的商品id)

  • express_no(物流單號)

因此在生產發貨申請單時,先得調用第三方物流公司的接口申請一個物流單,這樣發貨申請單中是有一個物流單號的,並且每一個積分兌換記錄都經過id跟發貨申請單關聯起來。

這樣在頁面上對每一個兌換記錄,是否是能夠找到發貨申請單中的物流單號,而後根據物流單號調用第三方物流公司的接口,去獲取配送的進度?

這就是一個很是典型的業務系統的技術實現的邏輯思考,一個經驗豐富合格的工程師,每每都具有了必定的業務思惟,能夠很好的根據業務系統中的用戶邏輯來考慮,反推本身的系統技術實現邏輯。

上述整個過程,以下圖所示:


五、事務的保證

業務流程整個捋順以後,接下來就涉及到技術的考慮了。你得考慮一下,這種業務系統裏怎麼能沒有事務呢?

扣減積分、新增積分兌換記錄、新增發貨申請單,這三個步驟必須是要麼一塊兒完成,要麼一塊兒失敗的。也就是說,這三個步驟必須是在一個事務裏的。

如今有一個問題,對一個電商平臺自身的業務系統來講,僅僅包含積分服務。可是倉儲服務通常是獨立部署的一套系統,或者是一個獨立的服務。

也就是說,扣減積分和新增積分兌換記錄能夠在一個服務裏是一個事務,可是新增發貨申請單,他是在另一個服務裏的,這個事務如何保證呢?

有朋友可能立刻回答:用分佈式事務啊!先別急,我們能夠先用最簡單的模式來實現一下。

好比積分服務在一個事務代碼塊中,先執行扣減積分、新增積分兌換記錄兩個步驟。

而後記住,在事務代碼塊中,最後一步調用倉儲服務的接口,若是接口調用成功,那麼就能夠提交事務了。若是接口調用失敗,那麼就拋異常讓事務回滾,這樣能夠不能夠?

這個流程以下所示:

積分服務 事務 {

-> 扣減積分

-> 新增積分兌換記錄

-> 調用倉儲服務

}


六、消息中間件的引入

上述設計其實理論上是沒問題的,可是這裏你忽略了一個問題,在這個業務場景中,積分服務是沒有必要同步調用倉儲服務的。

由於積分兌換是一個用戶執行的操做,假設你的倉儲服務在生成發貨申請單的時候調用第三方物流公司的接口,被卡住了,或者失敗了,怎麼辦?

此時可能致使用戶在頁面上看到積分兌換按鈕點擊以後,卡在那兒可能幾十秒都沒法執行成功,因此這個系統如此設計是錯誤的。

那應該怎麼作呢?你必須得在這裏引入消息中間件進行異步化的解耦,保證用戶點擊積分兌換按鈕以後,儘快返回。以下圖所示:




七、重試機制的引入

到這裏就OK了嗎?還沒呢!

一旦引入消息中間件以後,好處是用戶點擊積分兌換按鈕,直接就是在積分服務里扣減積分以及新增積分兌換記錄,而後發送一條消息到消息中間件裏就結束了,速度很快,保證了用戶體驗。

可是壞處就是,萬一倉儲服務執行新增發貨申請失敗了怎麼辦?

這個時候就須要引入可靠消息服務了,他須要去保證倉儲服務必定會完成新增發貨申請這個事。

具體的流程以下:

  • 積分服務發送消息給可靠消息服務,可靠消息服務在消息表中新增記錄,而後發送消息到MQ(消息中間件)

  • 而後倉儲服務消費消息新增發貨申請單,若是成功就回調可靠消息服務的一個接口說本身成功了,可靠消息服務就能夠更新本地消息表中的記錄狀態爲成功

  • 若是倉儲服務長時間沒通知可靠消息服務本身成功了,可靠消息服務不停的重試再次發送消息

經過這樣的設計,就能夠保證可靠消息服務必定會無限次重試保證讓倉儲服務成功執行。再加上重試機制後,整個流程圖以下所示:



八、引入冪等性機制

最後一個問題,若是倉儲服務卡在第三方物流系統申請物流單的環節,長時間阻塞,因此沒回調通知可靠消息服務。

可是可靠消息服務過了一段時間,感受沒收到回調通知,就本身重試發送了消息,這樣豈不是會讓倉儲服務新增兩條發貨申請單?

所以咱們還要保證倉儲服務新增發貨申請單的冪等性,其實也很是簡單,回顧一下發貨申請單表的結構:

發貨申請表

  • id(自增id主鍵)

  • type(發貨類型,1:購買,2:積分兌換)

  • credit_exchange_id(積分兌換表的id)

  • product_id(要發貨的商品id)

  • express_no(物流單號)

只要在「credit_exchange_id」字段上創建一個惟一索引就能夠了,保證每一個積分兌換記錄只能建立一條發貨申請單,若是重複建立就會被惟一索引被阻止,這樣就能夠保證這個行爲的冪等性了。

至此,對這道系統設計題目的回答,所有結束。


九、對這類面試題的總結

經過這篇文章的分析,能夠看到對這類開放式面試題的一個回答思路,首先得從業務上來考慮這個系統應該有哪些業務組成部分,如何實現業務流程?

其次就是你得考慮面臨對應的業務場景的時候,這個系統會有哪些技術挑戰,各個環節可能會有哪些技術問題?

而後應該針對這些技術挑戰和技術問題,現場給出一些你的思路。只要給出大體的思路就能夠,好比應該往哪一個方向去解決,應該引入哪些機制。

說實話,大部分人是沒實際作過這類系統的。好比讓你設計一個秒殺系統,如何設計?

試問,國內有多少人真的作過秒殺系統?其實面試官只不過是經過這個問題考察你的技術面、技術功底,對各類常規技術方案的積累,以及現場分析業務,分析技術問題,進而基於你過去的技術積累,給出合理解決方案的一個能力。

這種能力,是一個高級Java工程師必須具有的能力,由於若是你是一個有5年以上經驗的高級工程師,那你必須在團隊裏能獨立負責一個系統。

此時你必須有這個能力,對項目面臨的問題,要可以分析業務,分析技術問題,而後給出合理的技術方案和架構設計。

END


做者簡介:

原子彈大俠,阿里高級技術專家

經歷過每日百億流量的互聯網系統架構,尤爲對上億用戶場景下的高併發系統架構設計以及性能優化相關領域有深刻的研究。

END


長按下圖二維碼,即刻關注【狸貓技術窩】 阿里、京東、美團、字節跳動 頂尖技術專家坐鎮 爲IT人打造一個 「有溫度」 的技術窩!

做者:狸貓技術窩 連接:https://juejin.im/post/5cd992e6f265da03867e71c7 來源:掘金 著做權歸做者全部。商業轉載請聯繫做者得到受權,非商業轉載請註明出處。
相關文章
相關標籤/搜索