日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > windows >内容正文

windows

库存系统难破题?京东到家来分享

發布時間:2025/4/5 windows 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 库存系统难破题?京东到家来分享 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

http://www.sohu.com/a/194461959_467759

目前,京東到家庫存系統經歷兩年多的線上考驗與技術迭代,現服務著萬級商家、十萬級店鋪的規模,在需求變更與技術演進中,如何做到系統的穩定性與高可用?下面將會給你揭曉答案。

庫存系統技術架構

庫存系統技術架構圖

上圖如果進行總結下,主要體現出以下幾個方面:

完善的基礎設施

強大的基礎服務平臺讓應用、JVM、Docker、物理機所有健康指標一目了然,7*24 小時智能監控告警讓開發無須一直盯著監控;

數據驅動

數據與業務相輔相成,用數據驗證業務需求,迭代業務需求,讓業務需求都盡可能的收益最大化,庫存系統的開發同學只需要關注業務需求;

健全的測試團隊

大版本上線前相應的測試同學會跟進壓測,防止上線后潛在的性能瓶頸。

庫存系統技術架構圖解釋說明

Portal

通過提供商家 PC 端、App 端解決大部分中小商家的日常運營需求,另外提供開放平臺滿足大中型商家系統對接與數據共享互通的問題。

Service

這個板塊涵蓋了整個庫存最核心的 C&B 數據業務。

1、業務類

  • C 正常流程:用戶下單 - 商家揀貨 - 快遞員妥投

  • C 異常流程 - 缺貨:用戶下單 - 商家缺貨 - 用戶協商 - 調整訂單缺貨商品 - 商家揀貨 - 快遞員妥投

  • C 異常流程 - 取消:用戶下單 - 用戶反悔 - 訂單取消

  • C 異常流程 - 風控:用戶下單 - 風控攔截 - 訂單鎖定 - 客服審核 - 訂單取消 / 繼續生產

  • B 正常流程:商家維護可售庫存數量,即時或者定時生效

2、數據類

除了業務類需求外,京東到家還提供了大量有商業價值的數據供商家作業務決策,比如:

  • 商品銷量 Top 榜 - 支持分城市分類目篩選

  • 熱銷商品庫存不足預警 - 商家 App 版本 Push 通知及待辦事項中可以醒目識別這部分商品并進行維護

  • 紅黃線自動下架 - 近七日訂單量大于 5 單,并且被踩率大于等于 20% 的商品,進行下架操作,每日執行。

  • 庫存交易流水

3、中間件類

古人行軍打仗,兵馬未動,糧草先行,對于系統來說亦是如此,編碼未動架構先行,架構的技術選型非常重要,在這里給大家分享京東技術體系上萬碼農都在使用的幾個中間件。

  • JSF,類似于 DUBBO, 是一款非常優秀的 RPC 層框架,可以解決應用間的數據通信問題,它最主要的優勢是長連接的實現以及高效的序列化組件。

  • JMQ,JMQ 是京東自主研發的一款消息中間件系統,具有高可用、數據高可靠等特性。廣泛應用于公司內部系統,包括訂單、支付、庫房、交易等場景。在庫存系統中會優先更新 Redis 緩存數據,并發送變更 MQ,供 MySQL 及 ES 異步更新。

  • O2OWORKER,早期淘寶開源的一款產品 TBSCHEDULE,不這個只適用于單項目管理,多個系統使用的話權限無法隔離,另外參數配置過于繁瑣,結合這兩點進行了重構,從而形成了現在的整個京東到家都在使用的任務管理平臺。

DB

1、MySQL

京東到家庫存系統使用的關系型數據庫是 MySQL,低成本、低耦合、輕量級,總之優勢多多。

2、Redis

豐富的數據結構 & 眾多的原子性命令支持,非常適合庫存系統進行緩存查詢及扣減操作。

3、ES

庫存系統的數據量非常大,首先 MySQL 數據庫通過水平擴容來解決單表數據量過大的問題,水平擴容的規則采取的是按門店維度進行分表(1. 目前京東到家還沒有到分庫的階段,2. 按門店維度進行分表數據量會相對均衡一些,所以沒有按照商家維度進行劃分)。

那么在商家 PC 端上查詢所有商品庫存及維護庫存時帶來了難度,比如查詢該商家下所有的商品有多少條,同時處于上架狀態的商品有哪些……,為了解決這一難題,引入了 ES,將數據統一存儲在 ES 集群中,解決一些涉及到聚合查詢的場景。

庫存系統數據流轉

庫存系統數據流轉圖

庫存系統數據流轉圖解釋說明:

庫存系統的數據流轉,指的都是銷售庫存的數據流轉,在京東到家還有自營類業務板塊,即上圖中提到的城市倉,由于它涉及到采購入庫及盤盈盤虧等問題, 所以會由一套 WMS 系統來支撐。

京東到家設計初衷就是希望商家下的商品各門店共享,帶來的問題就是商家新建一個商品時,需要推送到商家下所有的門店中,即所有的門店均可以看到這個商品?;蛘呱碳倚陆ㄒ粋€門店時,需要將商家下所有的商品均推送到這個新建的門店中,所以這采用了 MQ 技術進行異步化批量處理。

寫到這里,相信對大家對庫存系統有了初步的了解,從上圖來看功能上其實并不復雜,但是他面臨的技術復雜度卻是相當高的,比如秒殺品在高并發的情況下如何防止超賣。

另外庫存系統還不是一個純技術的系統,需要結合用戶的行為特點來考慮,比如下文中提到什么時間進行庫存的扣減最合適,我們先拋出幾個問題和大家一起探討下,如有不妥之處,歡迎大家拍磚。

庫存什么時候進行預占 (或者扣減) 呢

商家銷售的商品數量是有限的,用戶下單后商品會被扣減,我們可以怎么實現呢?

舉個例子: 一件商品有 1000 個庫存,現在有 1000 個用戶,每個用戶計劃同時購買 1000 個。

  • 實現方案 1:如果用戶加入購物車時進行庫存預占,那么將只能有 1 個用戶將 1000 個商品加入購物車。

  • 實現方案 2:如果用戶提交訂單時進行庫存預占,那么將也只能有 1 個用戶將 1000 個商品提單成功,其它的人均提示“庫存不足,提單失敗”。

  • 實現方案 3:如果用戶提交訂單 & 支付成功時進行庫存預占,那么這 1000 個人都能生成訂單,但是只有 1 個人可以支付成功,其它的訂單均會被自動取消。

京東到家目前采用的是?方案 2,理由如下:

用戶可能只是暫時加入購物車,并不表示用戶最終會提單并支付。

所以在購物車進行庫存校驗并預占,會造成其它真正想買的用戶不能加入購物車的情況,但是之前加車的用戶一直不付款,最終損失的是公司。

方案 3 會造成生成 1000 個訂單,無論是在支付前校驗庫存還是在支付成功后再檢驗庫存,都會造成用戶準備好支付條件后卻會出現 99.9% 的系統取消訂單的概率,也就是說會給 99.9% 的用戶體驗到不爽的感覺。

數據表明用戶提交訂單不支付的占比是非常小的(相對于加入購物車不購買的行為),目前京東到家給用戶預留的最長支付時間是 30 分鐘,超過 30 分鐘訂單自動取消,預占的庫存自動釋放。

綜上所述,方案 2 也可能由于用戶下單預占庫存但最終未支付,造成庫存 30 分鐘后才能被其它用戶使用的情況,但是相較于方案 1,方案 3 無疑是折中的最好方案。

重復提交訂單的問題?

重復提交訂單造成的庫存重復扣減的后果是比較嚴重的。比如商家設置有 1000 件商品,而實際情況可能賣了 900 件就提示用戶無貨了,給商家造成無形的損失

可能出現重復提交訂單的情況:

  • 1、用戶善意行為:app 上用戶單擊“提交訂單”按鈕后由于后端接口沒有返回,用戶以為沒有操作成功會再次單擊“提交訂單”按鈕

  • 2、用戶惡意行為:黑客直接刷提單接口,繞過 App 端防重提交功能

  • 3、提單系統重試:比如提單系統為了提高系統的可用性,在第一次調用庫存系統扣減接口超時后會重試再次提交扣減請求

好了,既然問題根源縷清楚了,我們一一對癥下藥

  • 1、用戶善意行為:App 側在用戶第一次單擊“提交訂單”按鈕后對按鈕進行置灰,禁止再次提交訂單

  • 2、用戶惡意行為:采用令牌機制,用戶每次進入結算頁,提單系統會頒發一個令牌 ID(全局唯一),當用戶點擊“提交訂單”按鈕時發起的網絡請求中會帶上這個令牌 ID, 這個時候提單系統會優先進行令牌 ID 驗證,令牌 ID 存在 & 令牌 ID 訪問次數 =1 的話才會放行處理后續邏輯,否則直接返回

  • 3、提單系統重試:這種情況則需要后端系統(比如庫存系統)來保證接口的冪等性,每次調用庫存系統時均帶上訂單號,庫存系統會基于訂單號增加一個分布式事務鎖。

偽代碼如下:

庫存數據的回滾機制如何做?

需要庫存回滾的場景也是比較多的,比如:

  • 1、用戶未支付:用戶下單后后悔了

  • 2、用戶支付后取消:用戶下單 & 支付后后悔了

  • 3、風控取消:風控識別到異常行為,強制取消訂單

  • 4、耦合系統故障:比如提交訂單時提單系統 T1 同時會調用積分扣減系統 X1、庫存扣減系統 X2、優惠券系統 X3,假如 X1、X2 成功后,調用 X3 失敗,需要回滾用戶積分與商家庫存。

其中場景 1、2、3 比較類似,都會造成訂單取消,訂單中心取消后會發送 MQ 出來,各個系統保證自己能夠正確消費訂單取消 MQ 即可。

而場景 4 訂單其實尚未生成,相對來說要復雜些,如上面提到的,提單系統 T1 需要主動發起庫存系統 X2、優惠券系統 X3 的回滾請求(入參必須帶上訂單號),X2、X3 回滾接口需要支持冪等性。

其實針對場景 4,還存在一種極端情況,如果提單系統 T1 準備回滾時自身也宕機了,那么庫存系統 X2、優惠券系統 X3 就必須依靠自己來完成回滾操作了,也就是說具備自我數據健康檢查的能力,具體來說怎么實現呢?

可以利用當前訂單號所屬的訂單尚未生成的特點,可以通過 worker 機制,每次撈取 40 分鐘(這里的 40 一定要大于容忍用戶的支付時間)前的訂單,調用訂單中心查詢訂單的狀態,確保不是已取消的,否則進行自我數據的回滾。

多人同時購買 1 件商品,如何安全地庫存扣減?

現實中同一件商品可能會出現多人同時購買的情況,我們可以如何做到并發安全呢?

偽代碼片段 1:

偽代碼片段 1 的設計思想是所有的請求過來之后首先加鎖,強制其串行化處理,可見其效率一定不高。

偽代碼片段 2:

這段代碼只是在 where 條件里增加了and stockNum>="+requestBuyNum即可防止超賣的行為,達到了與上述偽代碼 1 的功能。

如果商品是促銷品(比如參與了秒殺的商品)并發扣減的機率會更高,那么數據庫的壓力會更高,這個時候還可以怎么做呢?

海量的用戶秒殺請求,本質上是一個排序,先到先得。但是如此之多的請求,注定了有些人是搶不到的,可以在進入上述偽代碼 Dao 層之前增加一個計數器進行控制,比如有 50% 的流量將直接告訴其搶購失敗,偽代碼如下:

另外同一個用戶,不允許多次搶購同一件商品,我們又該如何做呢?

如果同一個用戶擁有不同的帳號,來搶購同一件商品,上面的策略就失效了。一些公司在發展早期幾乎是沒有限制的,很容易就可以注冊很多個賬號。也即是網絡所謂的“僵尸賬號”,數量龐大,如果我們使用幾萬個“僵尸號”混進去搶購,這樣就可以大大提升我們中獎的概率,那我們如何應對呢?

庫存系統的核心表結構設計

下面列出了庫存系統的核心表結構,提供出來供大家在工作中能夠有所參考。

庫存主表,命名規則:stock_center_00~99 庫存主表

庫存流水表,命名規則:stock_center_flow_00~99 庫存流水表

庫存批量操作日志表,命名規則:batch_upload_log 庫存批量操作日志表

作者介紹

柳志崇,2008 年計算機專業畢業,一直從事于移動互聯網及 O2O 新零售業務領域的工作,參與過京東到家多個億級 PV 系統的研發與架構,對高并發有著豐富的實戰經驗。

本文是聊聊架構社群分享的內容。如果你也有好內容,歡迎你也來社群分享。

Q&A

Q:

億級 PV 系統的架構能否介紹下,怎么做到高并發的?

A:

高并發這個詞業內外使用得很泛濫,因為并沒有一個統一的定義,比如 qps、tps 達到多少就是高并發了。

一個系統設計的早期更多地關注功能迭代,隨著平臺的發展,用戶、商家、商品數據的持續增長,直到有一天有人告訴你,說你的系統太慢了,或者程序處理上的數據不對時,表明你是時候該重視高并發了。

接下來我談談關于庫存系統這塊高并發的思路,供參考。

  • 服務接口的無狀態化設計,方便隨時隨地可以水平擴容

  • 服務接口的冪等性設計,防止重復提交造成的重復扣減

  • 服務接口的限流與截流設計,應對異常流量造成整個系統癱瘓

  • 針對讀多寫少的場景進行數據緩存,緩存時還應該注意緩存擊穿的問題

  • 庫存數據持續增多時勢必會考慮數據庫分庫分表,分庫分表路由規則設計:1、一定要緊貼業務,否則在一些聚合查詢上非常麻煩;2、避免短期內出現二次擴容的可能性

關于庫存分庫或分表使用什么策略,京東到家接入的商家多半是優質商家,通常一個商家會有多個門店,目前庫存系統采用的門店維度進行分表:

1、目前的體量還沒有進行分庫;

2、分表路由算法是門店編號取模 + 大門店定向路由組合,來避免簡單的取模算法造成表數據分布可能出現的嚴重不平衡問題

Q:

為什么京東到家的庫存和京東商城的庫存要單獨的呢?

A:

京東商城與京東到家是兩款 App,兩款有著各自獨立的消費場景與目標人群,系統設計上是有些差異化的,如果我們從架構的角度來說,他們之間是解耦的,帶來顯而易見的好處就是其中一個掛了不會影響到另外一個。

京東到家比京東商城起步晚了整整 12 年,所以設計之初是借鑒了京東商城的庫存系統的,但是京東到家中涵蓋的服務類商品 (比如上門美甲按摩庫存是具體的人,而一個人是不能同時被預約提供服務的)、外賣類商品 (庫存相對更加簡單,通常只有貨品充足、貨品緊張、無貨幾種狀態) 是京東商城中沒有的。

另外京東到家處于一個產品高速迭代期,可能一周就一個版本,由于與京東商城相互獨立,有問題了影響也可以控制到很小。

Q:

1、定時 40 分撈取,萬一 39 分那時候服務重啟了,錯過這個定時任務撈取,怎么辦?

2、同一局域網中,如果對外 IP 都是同一個,受到限制那怎么辦?

3、取模限制一部分流量搶購失敗,萬一流量在促銷庫存量之內,那是不是最多只能賣出一半?從取???#xff0c;也就是 userID 被模為 1 的用戶,總是搶不到了?

A:

1、這個問題很好,問得很仔細,這一塊就考驗定時任務的調度機制了,首先調度策略是每分鐘執行,檢測前 40 分鐘到前 50 分鐘之間訂單

2、看 doBuy1 方法,這里其實提到了,當同一個公網 IP 訪問請求量超過了預設閾值,就會增加一個驗證碼環節

3、京東到家 App 目前 DAU 過百萬了,取模機制造成的只能賣出一半這個問題還沒有遇到過,不過有這個擔心是好的,實際開發過程中可以設這個取模的值為動態放行流量即可;另外你提到的 userId 被模 1,這個問題是不存在的,因為我不是用 userId 來取模的,請重新讀 buy 方法。

Q:

請問一下在高峰期每秒以下這個表會有多少的 tps?“庫存主表,命名規則:stock_center_00~99”

A:

首先這個表是異步更新的,不會阻塞主流程,目前觀察 tps 可以達到 800

Q:

如果是異步的話,就會有可能出現查庫存和實際庫存有差異。你是先把庫存都放 redis 然后再用 mq 扣減嗎?或者還是有其它解決方案?

A:

對外提供的 curd 都是基于 redis 的,所以不會出現不一致的問題,mysql 異步更新只是為了數據的持久化。

Q:

異地多活,用戶維度單元化下庫存是怎么處理的?

A:

異地多活,目前我們做到了服務的擴機房部署,數據的擴機房準實時備份,還沒有進行用戶維度的單元化。我也沒有實戰過,不過我覺得異地多活,架構設計有幾點需要關注:

  • 1、避免冷備,即如果一個機房不出意外,另外一個機房永遠就是一個 backup,對于大型互聯網公司這個成本是非常高的;

  • 2、機房同源策略,一個網絡請求可能涉及到幾個幾十個系統的協同,應當將這部分處理控制到同一個機房處理;

  • 3、就近訪問策略,通過智能 DNS,路由到離用戶最近的機房機房。

轉載于:https://www.cnblogs.com/davidwang456/articles/10251560.html

總結

以上是生活随笔為你收集整理的库存系统难破题?京东到家来分享的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。