秒殺系統(tǒng)設(shè)計

1.主要做到以下兩點:

  • 盡量將請求過濾在上游。

  • 盡可能的利用緩存(大多數(shù)場景下都是查多于寫)。

  • 如果流量巨大,導(dǎo)致各個層的壓力都很大可以適當?shù)募訖C器橫向擴容。如果加不了機器那就只有放棄流量直接返回失敗抒巢。快速失敗非常重要秉犹,至少可以保證系統(tǒng)的可用性蛉谜。

  • 業(yè)務(wù)分批執(zhí)行:對于下單稚晚、付款等操作可以異步執(zhí)行提高吞吐率。

  • 主要目的就是盡量少的請求直接訪問到 DB型诚。

2. 架構(gòu)圖

image.png
  • 前端請求進入 web 層客燕,對應(yīng)的代碼就是 controller。

  • 之后將真正的庫存校驗狰贯、下單等請求發(fā)往 Service 層(其中 RPC 調(diào)用依然采用的 dubbo也搓,只是更新為最新版本,本次不會過多討論 dubbo 相關(guān)的細節(jié)涵紊,有興趣的可以查看 基于dubbo的分布式架構(gòu))傍妒。

  • Service 層再對數(shù)據(jù)進行落地,下單完成

其實拋開秒殺這個場景來說正常的一個下單流程可以簡單分為以下幾步:

  • 校驗庫存

  • 扣庫存

  • 創(chuàng)建訂單

  • 支付

3.常見問題

3.1 超賣現(xiàn)象(使用樂觀鎖更新)

3.2 提高吞吐量

為了進一步提高秒殺時的吞吐量以及響應(yīng)效率摸柄,這里的 web 和 Service 都進行了橫向擴展颤练。

  • web 利用 Nginx 進行負載。

  • Service 也是多臺應(yīng)用

3.2當并發(fā)量達到幾百萬時(分布式限流)

我們將并發(fā)控制在一個可控的范圍之內(nèi)塘幅,然后快速失敗這樣就能最大程度的保護系統(tǒng)昔案。

3.3 sql查詢太多(redis緩存)

這種數(shù)據(jù)我們完全可以放在內(nèi)存中,效率比在數(shù)據(jù)庫要高很多电媳。

由于我們的應(yīng)用是分布式的,所以堆內(nèi)緩存顯然不合適庆亡,Redis 就非常適合匾乓。

這次主要改造的是 Service 層:

  • 每次查詢庫存時走 Redis。

  • 扣庫存時更新 Redis又谋。

  • 需要提前將庫存信息寫入 Redis(手動或者程序自動都可以)拼缝。

3.4請求同步轉(zhuǎn)異步(kafka)

這里我們將寫訂單以及更新庫存的操作進行異步化,利用 Kafka 來進行解耦和隊列的作用彰亥。

每當一個請求通過了限流到達了 Service 層通過了庫存校驗之后就將訂單信息發(fā)給 Kafka 咧七,這樣一個請求就可以直接返回了。

消費程序再對數(shù)據(jù)進行入庫落地任斋。

因為異步了继阻,所以最終需要采取回調(diào)或者是其他提醒的方式提醒用戶購買完成。

4. 總結(jié)

其實經(jīng)過上面的一頓優(yōu)化總結(jié)起來無非就是以下幾點:

  • 盡量將請求攔截在上游废酷。

  • 還可以根據(jù) UID 進行限流瘟檩。

  • 最大程度的減少請求落到 DB。

  • 多利用緩存澈蟆。

  • 同步操作異步化墨辛。

  • fail fast,盡早失敗趴俘,保護應(yīng)用睹簇。

5擎椰、悲觀鎖

簡單理解下悲觀鎖:當一個事務(wù)鎖定了一些數(shù)據(jù)之后,只有當當前鎖提交了事務(wù)敬飒,釋放了鎖刑枝,其他事務(wù)才能獲得鎖并執(zhí)行操作。

這里使用select for update的方式利用數(shù)據(jù)庫開啟了悲觀鎖垛叨,鎖定了id=1的這條數(shù)據(jù)(注意:這里除非是使用了索引會啟用行級鎖伦糯,不然是會使用表鎖,將整張表都鎖住嗽元。)敛纲。之后使用commit提交事務(wù)并釋放鎖,這樣下一個線程過來拿到的就是正確的數(shù)據(jù)剂癌。

悲觀鎖一般是用于并發(fā)不是很高淤翔,并且不允許臟讀等情況。但是對數(shù)據(jù)庫資源消耗較大佩谷。

6.樂觀鎖

那么有沒有性能好旁壮,支持的并發(fā)也更多的方式呢?

那就是樂觀鎖谐檀。

樂觀鎖是首先假設(shè)數(shù)據(jù)沖突很少抡谐,只有在數(shù)據(jù)提交修改的時候才進行校驗,如果沖突了則不會進行更新桐猬。

通常的實現(xiàn)方式增加一個version字段麦撵,為每一條數(shù)據(jù)加上版本。每次更新的時候version+1溃肪,并且更新時候帶上版本號

實踐:基于分布式微服務(wù)的秒殺搶購功能的實現(xiàn)

借下圖

image.png

樂優(yōu).png

秒殺設(shè)計到的微服務(wù)

  1. 注冊中心(Eurake) : @EnableEurekaServer開啟注冊中心免胃,實現(xiàn)對各種微服務(wù)的集中管理

  2. 網(wǎng)關(guān)徽服務(wù)(zuul) : @EnableDiscoveryClient將服 務(wù)注冊到到注冊中心,@EnablezuulProxy開啟 網(wǎng)關(guān)服務(wù)惫撰,對微服務(wù)路口做統(tǒng)一管理羔沙, 實現(xiàn)路由,降級(容錯回退)厨钻,限流的功能扼雏。如果多臺服務(wù)器,可以通過路徑和服務(wù)的綁定path: /user-service/* ; serviceld: user-service2,實現(xiàn)負載均衡(默認是Ribbon輪詢莉撇,還有隨機)

  3. 用戶中心微服務(wù)(user-service) :@EnableDiscoveryClient將 用戶中心微服務(wù)注冊到到注冊中心呢蛤,實現(xiàn)注冊和登錄功能

  4. 授權(quán)中心微服務(wù)(auth-service) : @EnableDiscoveryClient將用戶中心微服務(wù)注冊到到注冊中心實現(xiàn)對登錄的鑒權(quán)。

  5. 商品微服務(wù)(item-service) : @EnableDiscoveryClient將商品微服務(wù)注冊到到注冊中心棍郎,做商品的添加和查詢其障。

具體秒殺流程邏輯

  1. 網(wǎng)關(guān)對部分不需要登錄認證的接口放行(要優(yōu)化)1.注冊用戶,網(wǎng)關(guān)對注冊放行

  2. 登錄接口到網(wǎng)關(guān)涂佃,被路由到授權(quán)中心励翼,授權(quán)中心微服務(wù)調(diào)用用戶中心的登錄接口進行校驗蜈敢,校驗成功,利用JWT生成token,然后利用RSA非對稱加密token,生成公鑰和私鑰保存汽抚,然后將token返回到客戶端

秒殺業(yè)務(wù)
  1. 在商品微服務(wù)中設(shè)置秒殺參數(shù)抓狭,根據(jù)參數(shù)的商品Id查詢商品,構(gòu)建商品秒殺表造烁,添加否过,然后更新redis緩存
BoundHashOperations<String, Object, Object> hashOperations = this.stringRedisTemplate.boundHashOps(KEY PREFIX);

1/判斷是否存在此K值

if (hashOperations.hasKey(KEY PREFI){

hashOperations.delete(KEY_ PREFIX);

seckiloods.forEach(goods > hashOperatiosput(goos.getkud(.totring(), goods.getstock).totrin));))
  1. 使用秒殺功能需要登錄驗證,創(chuàng)建登錄攔截(LoginInterceptor extends HandlerinterceptorAdapter)對token進行驗證惭蟋,認證通過將用戶信息存放到線程域中苗桂,并且走一個限流攔截AccessInterceptor extends HandlerinterceptorAdapter)實現(xiàn)限流功能

  2. 構(gòu)建秒殺路徑(限流),加密告组,保存到redis緩存,隱藏秒殺路徑煤伟,防止刷單。

4. 秒殺

4.1. 驗證秒殺路徑

4.2. 讀取庫存木缝, 減1后更新緩存

4.3. 庫存不足直接返回“排隊中”

4.4. 庫存充足便锨, 將商品信息封裝入隊MQ,然后直接返回“排隊中”

  1. 然后訂單微服務(wù)監(jiān)聽隊列,消費隊列我碟,

5.1判斷庫存不足放案,將該商品設(shè)置成不可秒殺狀態(tài),

5.2查看是否秒殺到怎囚,秒殺到直接返回卿叽,

5.3沒有秒殺到,創(chuàng)建訂單

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末恳守,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子贩虾,更是在濱河造成了極大的恐慌催烘,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,372評論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件缎罢,死亡現(xiàn)場離奇詭異伊群,居然都是意外死亡,警方通過查閱死者的電腦和手機策精,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,368評論 3 392
  • 文/潘曉璐 我一進店門舰始,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人咽袜,你說我怎么就攤上這事丸卷。” “怎么了询刹?”我有些...
    開封第一講書人閱讀 162,415評論 0 353
  • 文/不壞的土叔 我叫張陵谜嫉,是天一觀的道長萎坷。 經(jīng)常有香客問我,道長沐兰,這世上最難降的妖魔是什么哆档? 我笑而不...
    開封第一講書人閱讀 58,157評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮住闯,結(jié)果婚禮上瓜浸,老公的妹妹穿的比我還像新娘。我一直安慰自己比原,他們只是感情好插佛,可當我...
    茶點故事閱讀 67,171評論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著春寿,像睡著了一般朗涩。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上绑改,一...
    開封第一講書人閱讀 51,125評論 1 297
  • 那天谢床,我揣著相機與錄音,去河邊找鬼厘线。 笑死识腿,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的造壮。 我是一名探鬼主播渡讼,決...
    沈念sama閱讀 40,028評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼耳璧!你這毒婦竟也來了成箫?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,887評論 0 274
  • 序言:老撾萬榮一對情侶失蹤旨枯,失蹤者是張志新(化名)和其女友劉穎蹬昌,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體攀隔,經(jīng)...
    沈念sama閱讀 45,310評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡皂贩,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,533評論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了昆汹。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片明刷。...
    茶點故事閱讀 39,690評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖满粗,靈堂內(nèi)的尸體忽然破棺而出辈末,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 35,411評論 5 343
  • 正文 年R本政府宣布本冲,位于F島的核電站准脂,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏檬洞。R本人自食惡果不足惜狸膏,卻給世界環(huán)境...
    茶點故事閱讀 41,004評論 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望添怔。 院中可真熱鬧湾戳,春花似錦、人聲如沸广料。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽艾杏。三九已至韧衣,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間购桑,已是汗流浹背畅铭。 一陣腳步聲響...
    開封第一講書人閱讀 32,812評論 1 268
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留勃蜘,地道東北人硕噩。 一個月前我還...
    沈念sama閱讀 47,693評論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像缭贡,于是被迫代替她去往敵國和親炉擅。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,577評論 2 353

推薦閱讀更多精彩內(nèi)容

  • 什么是秒殺 通俗一點講就是網(wǎng)絡(luò)商家為促銷等目的組織的網(wǎng)上限時搶購活動 比如說京東秒殺阳惹,就是一種定時定量秒殺谍失,在規(guī)定...
    zwb_jianshu閱讀 659評論 0 1
  • 什么是秒殺 通俗一點講就是網(wǎng)絡(luò)商家為促銷等目的組織的網(wǎng)上限時搶購活動 比如說京東秒殺,就是一種定時定量秒殺莹汤,在規(guī)定...
    zwb_jianshu閱讀 553評論 0 0
  • 什么是秒殺 通俗一點講就是網(wǎng)絡(luò)商家為促銷等目的組織的網(wǎng)上限時搶購活動 比如說京東秒殺袱贮,就是一種定時定量秒殺,在規(guī)定...
    碼道功臣閱讀 6,033評論 2 79
  • 每天做一些之前未能堅持的事体啰。比如寫作,讀書(包括日文書嗽仪,英文書)荒勇,鍛煉,烘培闻坚,戒微信沽翔。 每個人都希望自己是被需要的...
    Mini的世界閱讀 360評論 0 0
  • 望岳三首·其三 [唐代]杜甫 南岳配朱鳥, 秩禮自百王。 欻吸領(lǐng)地靈仅偎, 鴻洞半炎方跨蟹。 邦家用祀典, 在德非馨香橘沥。 ...
    修源正本閱讀 232評論 0 1