日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網(wǎng)為廣大站長提供免費收錄網(wǎng)站服務(wù),提交前請做好本站友鏈:【 網(wǎng)站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(wù)(50元/站),

點擊這里在線咨詢客服
新站提交
  • 網(wǎng)站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會員:747

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

服務(wù)劃分

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

 

服務(wù)說明

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

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

上面劃分的每一個服務(wù)都是獨立部署運行的服務(wù)。

服務(wù)

說明

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

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

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

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

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

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

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

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

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

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

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

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

 

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

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

  1. 鏈路 1.1 ~ 1.3 提交訂單
  2. 鏈路 2.1 ~ 2.4 消費下單消息(下單業(yè)務(wù)處理)
  3. 鏈路 3.1 ~ 3.2 查詢下單結(jié)果
  4. BFF(小程序的后端,負(fù)責(zé)聚合和適配)
秒殺場景下訂單中心的架構(gòu)設(shè)計

 

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

  1. 后臺連接獨立的專有讀庫,與前臺隔離,不能因為后臺的查詢影響前臺的操作
  2. 后臺的訂單查詢可以調(diào)用搜索服務(wù)和讀庫來完成
  3. 后臺的增刪改操作調(diào)用 order-core(訂單核心服務(wù))進(jìn)行操作,不能直接操作數(shù)據(jù)庫
秒殺場景下訂單中心的架構(gòu)設(shè)計

 

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

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

 

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

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

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

 

  1. 訂單調(diào)度服務(wù)查詢專有的讀庫
  2. 寫操作調(diào)用 order-core(訂單核心服務(wù))查詢來完成

下單流程

下單請求通過 MQ 異步化處理,下單處理結(jié)果存入 redis,前端輪詢下單結(jié)果。

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

 

步驟說明

步驟 1:提交訂單說明

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

步驟 2:消費下單請求說明

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

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

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

核心表分庫

1. 以訂單主表和訂單明細(xì)表為例進(jìn)行分庫設(shè)計,假如按 32 個庫進(jìn)行分庫。

2. 訂單主表和訂單明細(xì)表通過訂單號進(jìn)行關(guān)聯(lián)。

3. 分庫要求:

  • 某個用戶的所有訂單在同一個庫,避免跨庫查詢(可根據(jù)用戶 id——buyerId 定位到分庫編號)
  • 某個商家的所有訂單在同一個庫,避免跨庫查詢(可根據(jù)商家 id——sellerId 定位到分庫編號)
  • 可以根據(jù)訂單號查詢(可根據(jù)訂單號定位到分庫編號)

4. 按照以上分庫要求,做出以下分庫設(shè)計

  • 訂單主表進(jìn)行冗余,訂單主表分成用戶訂單主表(buyer_order)和商家訂單主表(seller_order)
  • 用戶訂單主表(buyer_order)按照 buyerId % 32 進(jìn)行分庫
  • 商家訂單主表(seller_order)按照 sellerId %32 進(jìn)行分庫
  • 訂單號末位帶上分庫編號,分庫編號為 buyerId % 32
  • 訂單明細(xì)表(order_detail)按照訂單號進(jìn)行分庫,確保同一個訂單的明細(xì)在同一個庫
  • 用戶訂單主表(buyer_order)同步寫入,因為訂單是由用戶發(fā)起的,需要保證實時性。
  • 商家訂單主表(seller_order)建議保證最終一致性即可,可根據(jù)實際業(yè)務(wù)選擇同步雙寫或者通過 MQ 異步寫入

5. 分庫設(shè)計圖:

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

 

庫存扣減方案

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

庫存扣減序列圖

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

 

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

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

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

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

關(guān)于釋放庫存

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

其他

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

分享到:
標(biāo)簽:架構(gòu) 設(shè)計
用戶無頭像

網(wǎng)友整理

注冊時間:

網(wǎng)站:5 個   小程序:0 個  文章:12 篇

  • 51998

    網(wǎng)站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會員

趕快注冊賬號,推廣您的網(wǎng)站吧!
最新入駐小程序

數(shù)獨大挑戰(zhàn)2018-06-03

數(shù)獨一種數(shù)學(xué)游戲,玩家需要根據(jù)9

答題星2018-06-03

您可以通過答題星輕松地創(chuàng)建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學(xué)四六

運動步數(shù)有氧達(dá)人2018-06-03

記錄運動步數(shù),積累氧氣值。還可偷

每日養(yǎng)生app2018-06-03

每日養(yǎng)生,天天健康

體育訓(xùn)練成績評定2018-06-03

通用課目體育訓(xùn)練成績評定