自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

秒殺場(chǎng)景下訂單中心的架構(gòu)設(shè)計(jì)

開(kāi)發(fā) 前端
Java 程序總是從主類(lèi)的 main 方法開(kāi)始執(zhí)行,main 方法就是 ?Java 程序默認(rèn)的主線程,而在 main 方法中再創(chuàng)建的線程就是其他線程。

不管是普通場(chǎng)景的下單,還是秒殺場(chǎng)景的下單,對(duì)訂單中心來(lái)說(shuō),都是下單,關(guān)鍵是要能支撐秒殺瞬間大量的下單請(qǐng)求。本文探討一下通用的訂單中心架構(gòu),主要從服務(wù)劃分、下單請(qǐng)求處理流程、核心表分庫(kù)等方面來(lái)介紹,不區(qū)分普通下單還是秒殺下單,系統(tǒng)架構(gòu)設(shè)計(jì)做好了,有秒殺活動(dòng)時(shí),無(wú)非進(jìn)行一些擴(kuò)容、限流、降級(jí)等手段即可應(yīng)對(duì)。

服務(wù)劃分

服務(wù)說(shuō)明

我不希望整個(gè)訂單中心就是一個(gè)巨大的單體服務(wù),也不希望是太細(xì)的微服務(wù),我希望訂單中心是合理的“中服務(wù)”的組合。

可針對(duì)不同場(chǎng)景對(duì)服務(wù)進(jìn)行擴(kuò)容,比如訂單搜索請(qǐng)求量比較大,就適當(dāng)增加訂單搜索服務(wù)的實(shí)例數(shù)量;消費(fèi)速度慢,可針對(duì)訂單消費(fèi)者服務(wù)進(jìn)行優(yōu)化,調(diào)整服務(wù)實(shí)例數(shù)量。

上面劃分的每一個(gè)服務(wù)都是獨(dú)立部署運(yùn)行的服務(wù)。

服務(wù)

說(shuō)明

order-core(訂單核心服務(wù))

負(fù)責(zé)訂單的業(yè)務(wù)處理,直接和 DB 交互

order-search(訂單搜索服務(wù))

負(fù)責(zé)訂單索引的維護(hù)和搜索,直接和 ES 交互

order-job(訂單調(diào)度服務(wù))

訂單超時(shí)取消等調(diào)度任務(wù)

order-consumer(訂單消費(fèi)者服務(wù))

消費(fèi)訂單相關(guān)消息,如下單消息、訂單索引更新消息

order-manage(訂單管理后臺(tái)系統(tǒng))

訂單管理后臺(tái),數(shù)據(jù)來(lái)源于 ES 和從庫(kù)

應(yīng)用架構(gòu)圖

服務(wù)調(diào)用關(guān)系圖

提交訂單服務(wù)調(diào)用關(guān)系:

  • 鏈路 1.1 ~ 1.3 提交訂單
  • 鏈路 2.1 ~ 2.4 消費(fèi)下單消息(下單業(yè)務(wù)處理)
  • 鏈路 3.1 ~ 3.2 查詢下單結(jié)果
  • BFF(小程序的后端,負(fù)責(zé)聚合和適配)

后臺(tái)服務(wù)調(diào)用關(guān)系:

  • 后臺(tái)連接獨(dú)立的專有讀庫(kù),與前臺(tái)隔離,不能因?yàn)楹笈_(tái)的查詢影響前臺(tái)的操作
  • 后臺(tái)的訂單查詢可以調(diào)用搜索服務(wù)和讀庫(kù)來(lái)完成
  • 后臺(tái)的增刪改操作調(diào)用 order-core(訂單核心服務(wù))進(jìn)行操作,不能直接操作數(shù)據(jù)庫(kù)

訂單搜索或查看訂單詳情服務(wù)調(diào)用關(guān)系:

  • 訂單列表或者搜索訂單可以調(diào) order-search(訂單搜索服務(wù))來(lái)完成
  • 在訂單列表店家訂單明細(xì),可以根據(jù)訂單號(hào)由 order-core(訂單核心服務(wù))查詢從庫(kù)來(lái)完成

訂單調(diào)度服務(wù)調(diào)用關(guān)系:

  • 訂單調(diào)度服務(wù)查詢專有的讀庫(kù)
  • 寫(xiě)操作調(diào)用 order-core(訂單核心服務(wù))查詢來(lái)完成

下單流程

下單請(qǐng)求通過(guò) MQ 異步化處理,下單處理結(jié)果存入 Redis,前端輪詢下單結(jié)果。

步驟說(shuō)明

步驟 1:提交訂單說(shuō)明

  • order-core(訂單核心服務(wù))提供提交訂單接口(/order/submit)
  • 這個(gè)接口接收訂單相關(guān)的參數(shù),如商品 id、價(jià)格、數(shù)量等
  • 接收到請(qǐng)求后,做好基本參數(shù)校驗(yàn)
  • 生成唯一的訂單號(hào),組裝基本的訂單信息
  • 將訂單號(hào)和訂單創(chuàng)建中狀態(tài)存入 Redis
  • 發(fā)送 MQ,然后將訂單號(hào)返回給前端

步驟 2:消費(fèi)下單請(qǐng)求說(shuō)明

  • order-consumer(訂單消費(fèi)者服務(wù))獲取到下單請(qǐng)求消息后,調(diào)庫(kù)存中心接口進(jìn)行庫(kù)存預(yù)占
  • 如果庫(kù)存不足,預(yù)占失敗,則將訂單創(chuàng)建失敗狀態(tài)和失敗信息更新到 Redis,流程終止
  • 如果庫(kù)存充足,預(yù)占成功,則將訂單創(chuàng)建成功狀態(tài)更新到 Redis
  • 調(diào)用 order-core(訂單核心服務(wù))保存訂單信息到數(shù)據(jù)庫(kù),調(diào)用 order-search(訂單搜索服務(wù))對(duì)訂單進(jìn)行索引
  • 發(fā)送創(chuàng)建訂單結(jié)果消息,庫(kù)存中心根據(jù)創(chuàng)單結(jié)果消息進(jìn)行庫(kù)存扣減或者釋放

步驟 3:根據(jù)訂單號(hào)查詢輪詢下單結(jié)果說(shuō)明

  • order-core(訂單核心服務(wù))提供根據(jù)訂單號(hào)查詢訂單是否已創(chuàng)建接口(/order/is-created)
  • 該接口返回報(bào)文應(yīng)包括,訂單號(hào)、訂單創(chuàng)建狀態(tài)(創(chuàng)建中,創(chuàng)建成功,創(chuàng)建失敗)、創(chuàng)建失敗原因
  • 前端定時(shí)輪詢?cè)摻涌?,查詢訂單是否?chuàng)建成功,輪詢頻率可根據(jù)實(shí)際情況進(jìn)行調(diào)整,比如 20ms 一次
  • 輪詢到訂單創(chuàng)建成功,可直接喚起支付,失敗則直接提示失敗信息

核心表分庫(kù)

  • 以訂單主表和訂單明細(xì)表為例進(jìn)行分庫(kù)設(shè)計(jì),假如按 32 個(gè)庫(kù)進(jìn)行分庫(kù)。
  • 訂單主表和訂單明細(xì)表通過(guò)訂單號(hào)進(jìn)行關(guān)聯(lián)。
  • 分庫(kù)要求:

某個(gè)用戶的所有訂單在同一個(gè)庫(kù),避免跨庫(kù)查詢(可根據(jù)用戶 id——buyerId 定位到分庫(kù)編號(hào))

某個(gè)商家的所有訂單在同一個(gè)庫(kù),避免跨庫(kù)查詢(可根據(jù)商家 id——sellerId 定位到分庫(kù)編號(hào))

可以根據(jù)訂單號(hào)查詢(可根據(jù)訂單號(hào)定位到分庫(kù)編號(hào))

  • 按照以上分庫(kù)要求,做出以下分庫(kù)設(shè)計(jì)

訂單主表進(jìn)行冗余,訂單主表分成用戶訂單主表(buyer_order)和商家訂單主表(seller_order)

用戶訂單主表(buyer_order)按照 buyerId % 32 進(jìn)行分庫(kù)

商家訂單主表(seller_order)按照 sellerId %32 進(jìn)行分庫(kù)

訂單號(hào)末位帶上分庫(kù)編號(hào),分庫(kù)編號(hào)為 buyerId % 32

訂單明細(xì)表(order_detail)按照訂單號(hào)進(jìn)行分庫(kù),確保同一個(gè)訂單的明細(xì)在同一個(gè)庫(kù)

用戶訂單主表(buyer_order)同步寫(xiě)入,因?yàn)橛唵问怯捎脩舭l(fā)起的,需要保證實(shí)時(shí)性。

商家訂單主表(seller_order)建議保證最終一致性即可,可根據(jù)實(shí)際業(yè)務(wù)選擇同步雙寫(xiě)或者通過(guò) MQ 異步寫(xiě)入

  • 分庫(kù)設(shè)計(jì)圖:

庫(kù)存扣減方案

  • 采用預(yù)占庫(kù)存方案:創(chuàng)建訂單時(shí)預(yù)占庫(kù)存
  • 庫(kù)存不足,預(yù)占失敗,下單失敗
  • 庫(kù)存足夠,預(yù)占成功,創(chuàng)建訂單
  • 訂單創(chuàng)建成功,扣減庫(kù)存;創(chuàng)建訂單失敗或者取消訂單,釋放庫(kù)存

庫(kù)存扣減序列圖

庫(kù)存設(shè)置到 redis 中,已 skuId 為 key,變化的數(shù)量為值,如:

  • 將 skuId=10086 的庫(kù)存值初始化為 100,redis.incrby(10086, 100)
  • 庫(kù)存初始化后,只能對(duì)庫(kù)存進(jìn)行加減操作,不允許做覆蓋操作

Redis 如何與數(shù)據(jù)庫(kù)中的庫(kù)存保持一致:

  • Redis 和數(shù)據(jù)庫(kù)的庫(kù)存保持最終一致性
  • 庫(kù)存被預(yù)占時(shí),生成庫(kù)存預(yù)占流水,關(guān)鍵字段有,訂單號(hào)、skuId、預(yù)占數(shù)量、流水狀態(tài)有(預(yù)占中、已扣減、已釋放),預(yù)占超時(shí)時(shí)間,同時(shí)可以在 Redis 或者數(shù)據(jù)庫(kù)中維護(hù)一個(gè) skuId 對(duì)應(yīng)的總預(yù)占數(shù)量字段,總預(yù)占數(shù)量 + 預(yù)占數(shù)量
  • 訂單中心發(fā)送庫(kù)存扣減消息,庫(kù)存中心消費(fèi)消息時(shí)更新庫(kù)存流水狀態(tài)為已扣減,總預(yù)占數(shù)量 - 預(yù)占數(shù)量
  • 訂單中心發(fā)送庫(kù)存釋放消息,庫(kù)存中心消費(fèi)消息時(shí)更新庫(kù)存流水狀態(tài)為已釋放,返還庫(kù)存到 Redis,總預(yù)占數(shù)量 - 預(yù)占數(shù)量
/**
* 預(yù)占庫(kù)存 偽代碼
* @param orderNo 訂單號(hào)
* @param skuId sku 標(biāo)識(shí)
* @param quantity 預(yù)占數(shù)量
*/
boolean preOccupy(String orderNo, String skuId, int quantity) {
boolean isPreOccupySuccess = false;
int value = redis.decrby(skuId, quantity);
if (value >= 0) {
// 庫(kù)存充足
// 生成庫(kù)存預(yù)占流水記錄
//(關(guān)鍵字段:orderNo,skuId,quantity,state(0-預(yù)占中;1-已扣減;2-已釋放),timeout(超時(shí)時(shí)間)
isPreOccupySuccess = true;
} else {
// 庫(kù)存不足,返還剛才預(yù)占的庫(kù)存
redis.incrby(skuId, qunatity);
}
return isPreOccupySuccess;
}

數(shù)據(jù)庫(kù)的庫(kù)存數(shù)量禁止覆蓋更新!

數(shù)據(jù)庫(kù)的庫(kù)存數(shù)量禁止覆蓋更新!
扣減庫(kù)存?zhèn)?SQL:update stock set stock_num = stock_num - 變化的值 where sku_id = 10086

關(guān)于釋放庫(kù)存

對(duì)一些釋放異常的情況,可由庫(kù)存中心調(diào)度服務(wù),找出庫(kù)存預(yù)占流水狀態(tài)為預(yù)占中且預(yù)占超時(shí)的記錄,根據(jù)訂單號(hào)向訂單中心確認(rèn)該訂單號(hào)的庫(kù)存是已扣減還是已釋放,再進(jìn)行相應(yīng)業(yè)務(wù)處理。

其他

除了以上大的方面設(shè)計(jì),分布式事務(wù)、冪等、補(bǔ)償、壓測(cè)……這些點(diǎn)是大家在設(shè)計(jì)系統(tǒng)時(shí)都需要考慮的,不在本文討論范圍。

責(zé)任編輯:武曉燕 來(lái)源: 今日頭條
相關(guān)推薦

2021-05-19 08:17:35

秒殺場(chǎng)景高并發(fā)

2021-10-27 10:48:49

架構(gòu)運(yùn)維技術(shù)

2020-07-15 18:01:15

騰訊云MySQL 8.0電商

2024-10-08 10:10:00

削峰高并發(fā)流量

2025-02-04 15:48:21

悲觀鎖數(shù)據(jù)庫(kù)應(yīng)用

2023-04-07 17:44:43

2022-03-25 10:48:40

NBF架構(gòu)設(shè)計(jì)

2020-04-22 10:43:49

高并發(fā)數(shù)據(jù)阿里巴巴

2017-07-06 00:27:17

虛擬訂單中心京東數(shù)據(jù)

2024-06-18 08:07:50

存儲(chǔ)架構(gòu)設(shè)計(jì)

2024-10-15 11:04:18

2018-03-18 08:28:04

數(shù)據(jù)中心運(yùn)維組織架構(gòu)數(shù)據(jù)中心

2019-11-14 09:32:16

程序員MySQLRedis

2025-04-15 04:00:00

2018-11-08 15:10:02

阿里雙十一架構(gòu)

2024-05-27 08:32:45

2013-05-27 10:58:28

Tumblr架構(gòu)設(shè)計(jì)雅虎收購(gòu)

2023-05-12 08:06:46

Kubernetes多云架構(gòu)

2024-12-09 13:23:28

2022-03-25 07:52:01

數(shù)據(jù)中心架構(gòu)HBase
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)