成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

如果讓你設計一個秒殺系統,你會怎么做?

開發 架構
秒殺本來就是一個看運氣的事,誰秒到算誰的,沒秒到就算失敗,產品數量往往有限,秒到的必然是少數人,所以在請求從客戶端到達服務端并處理的過程中,可以對流量進行層層過濾。

這個算是一個經典面試題了,雖說是一個場景題,但是也算是老八股了。

今天就從系統設計的角度來和小伙伴們聊一聊這個話題。

一般來說秒殺系統需要考慮到下面這樣一些問題:

  1. 瞬時高并發流量
  2. 熱點商品數據
  3. 庫存管理
  4. 重復下單
  5. 黃牛

接下來我們就這里提到的點逐一進行分析。

一 瞬時高并發流量

應對瞬時高并發流量,不是某一種方案就可以,是一個組合拳。另外大家要記得,系統設計沒有銀彈。

1.1 動靜分離部署

這算是一個基本要求了,引入 Nginx,將靜態資源和動態資源利用 Nginx 分流,靜態資源直接返回,動態資源則轉發給后端服務器去處理。

圖片圖片

這一點其實還蠻重要,松哥之前就有遇到這個問題,一開始沒有動靜分離部署,后來動靜分離部署之后,系統并發能力提升 2 倍以上

不過如果愿意花點錢,把靜態資源都交給云服務商的 CDN 來處理,那就更好了。

一般來說使用 CDN 是比較劃算的,因為 CDN 流量費往往比云主機的流量費便宜。

1.2 數據庫獨立部署

這個也算是基操了,將應用程序和數據庫部署到一起,往往無法讓數據庫發揮自己的極限性能。正常來說,一臺 1C2G 的服務器上只部署 MySQL,就能做到每秒處理 200 次查詢請求,這樣的數據基本上就能滿足一個每天 100W PV 的小網站了。

但是你想想,1C2G 的服務器部署 MySQL 和應用程序的話,估計卡的沒法用了。

將 MySQL 和應用程序部署到一臺服務器上,往往會因為兩者互相影響而降低整體的并發性能,具體來說可能會發生這些問題:

  1. 高并發導致 CPU 被耗盡,進而 MySQL 響應變慢。
  2. 應用程序處理請求的時候需要等待更長的時間獲取數據庫的數據,這個過程占用了大量的內存。
  3. 系統內存緊張導致 MySQL 中緩存的數據被回收,進而拖慢 MySQL。
  4. 如此循環往復,系統最終越來越慢甚至崩潰。

因此我們要做的第二件事情就是將數據庫和應用程序獨立分開部署。

1.3 流量過濾

秒殺本來就是一個看運氣的事,誰秒到算誰的,沒秒到就算失敗,產品數量往往有限,秒到的必然是少數人,所以在請求從客戶端到達服務端并處理的過程中,可以對流量進行層層過濾。

一般來說,請求主要經過如下節點:

圖片

由于秒殺的隨機性,我們可以這么做:

  1. Client 處也就是用戶請求發起的地方,我們就可以隨機丟棄一些請求,直接彈出秒殺失敗、網絡阻塞等等。
  2. 當請求到達 Nginx 之后,可以在 Nginx 處進行限流,利用像 limit_req_zone、limit_req_conn 等模塊來實現不同的限流策略。
  3. 當請求從 Nginx 上轉發到 Java 服務上之后,我們可以繼續使用一些限流工具,比如 Sentinel,或者自己利用 Redis 寫限流工具也可以,在這里繼續進行限流。
  4. 當請求突破層層關卡到達業務層之后,對于實時性要求不高的數據,直接從緩存查詢,緩存優先查本地緩存,其次是遠程分布式緩存如 Redis,緩存中沒有數據的話,最后再是 MySQL。

1.4 頁面靜態化

對于熱點數據頁面可以進行靜態化處理。

比如秒殺商品頁、秒殺商品詳情頁等等這些熱點頁面直接自動進行靜態化處理,這樣用戶每次訪問的時候,直接返回現成的頁面,就不用走數據庫了。

如果頁面數據發生變化,重新自動生成靜態頁面即可。

二 熱點商品數據

接下來就是熱點商品數據的處理了。

秒殺這種事情,在秒殺活動開始之前,我們基本上就能夠確定哪些數據是熱點數據了,所以處理處理起來相對來說并不難。

不過需要注意的是,能緩存的數據肯定是一些商品信息類的數據,對于像庫存這類實時性要求極高的數據,是不適合緩存的。

2.1 緩存預熱

緩存預熱主要從兩方面入手:

  1. 本地緩存預熱
  2. Redis 緩存預熱

查詢的時候先查本地緩存,沒有再查 Redis 緩存,這樣能夠有效避免 Redis 的熱 Key 問題。

2.2 數據拆分

另一方面就是我們要避免熱點數據聚集到一起,將熱點數據進行拆分。避免從一個緩存處去獲取多個熱點數據,這樣就能降低緩存的壓力。

比如:

  • 商品詳情數據
  • 價格數據
  • 秒殺規則數據
  • 。。。

可以對這些熱點數據進行拆分,其實拆分之后,熱點數據也就不那么“熱”了。

三 庫存管理

庫存因為實時性要求比較高,因此就不方便用緩存。

庫存管理要是做不好,可能會發生超賣或者少賣。

那么庫存管理怎么做呢?保險的方案當然就是直接去數據庫扣減,但是數據庫并發能力有限,所以往往還需要結合緩存來做。

我們分別來看。

3.1 數據庫扣減

數據庫扣減,為了避免把庫存扣成負數,一般來說我們有兩種思路:

  1. 悲觀鎖
  2. 樂觀鎖

在高并發場景下,悲觀鎖會導致更新效率降低很多;而樂觀鎖則會導致大量的失敗。似乎都不是一個很好的選擇。

其實我們只是要保證庫存不被減為負數而已,那么其實就可以在更新 SQL 中添加一個條件就行了,像下面這樣:

***** and 庫存>=0

大致上這樣就可以了。

不過只是這樣做還不夠,因為數據庫的并發能力在哪擺著呢。所以我們還是要利用緩存。

3.2 緩存扣減

由于 Redis 本身就是單線程執行的,因此我們再結合上 Lua 腳本,就可以保證扣減庫存這個操作的原子性。

在 Lua 腳本中我們可以獲取到庫存數據,然后判斷庫存,沒問題再進行扣減。

Redis 本身的高性能+單線程執行+Lua 腳本的原子性,這三點結合起來就可以確保上述操作是沒有問題的。

3.3 最佳實踐

在具體實踐中,往往是 3.1 和 3.2 結合起來。

具體流程是這樣:

首先 Redis 做扣減,扣減完了之后,發送一條消息給 MQ,應用程序再去消費這條消息,消費消息時完成數據庫的扣減。

這個過程中我們需要確保好 MQ 消息的可靠性和冪等性,處理好消息積壓。

當然,穩妥起見還需要有對賬機制,定時拉取 Redis 中的數據和數據庫中的數據進行對比,保證數據的一致性。

四 重復下單

秒殺場景下用戶由于比較焦急,頻繁點擊可能造成重復下單,因此我們需要處理好下單操作的冪等性。

這個也有很多思路,需要多管齊下。

4.1 前端置灰

前端用戶點擊之后,就對秒殺按鈕進行置灰操作,同時提醒用戶目前正在進行秒殺。

這是基操,但是不能從根本上解決問題,還得配合后段冪等性處理。

4.2 后端冪等性處理

后段冪等性處理有很多方案,可以利用 Token 機制,這個松哥之前也有很多文章介紹,不多說。

同時因為秒殺這種場景往往是限購的,因此在用戶下單的時候可以判斷是否有在途訂單或者用戶是否已經下單,進而決定當前下單操作是否能夠成功。

五 黃牛

薅羊毛的黃牛也是我們要考慮的一個問題。

5.1 識別黃牛

首先我們要識別出來哪些用戶可能是黃牛,一般來說,我們可以通過如下方式來識別:

  1. 請求頻率:監測用戶的請求頻率,若某一賬戶的請求過于頻繁,則可能是黃牛使用自動化工具發出的。
  2. 訪問模式:分析用戶的訪問模式,例如短時間內大量的重復請求或者非正常人類行為的訪問模式。
  3. IP 地址:檢查請求來源的 IP 地址,對于同一 IP 地址下頻繁的請求進行限制或標記。

如果公司有足夠的人力資源,這塊可以建立預測模型,通過模型去分析哪些人可能是黃牛。

5.2 防止黃牛

當我們識別出來黃牛之后,一般來說有如下一些辦法:

  • 圖形驗證碼(CAPTCHA):在關鍵環節加入圖形驗證碼,要求用戶識別并輸入相應的字符,以防止自動化工具的使用。
  • 滑動驗證:在關鍵環節采用滑動驗證等交互式驗證方式,這類驗證方式難以被自動化工具模擬,這也是大家目前見到的最多的驗證方式了。
  • 行為驗證:基于用戶的行為軌跡(如鼠標移動軌跡、鍵盤輸入模式等)來進行驗證,這個目前松哥只在京東圖書上見過這種驗證方式。
  • 請求頻率限制:對識別出來的用戶或 IP 地址的請求頻率進行限制,超出限制則暫時禁止訪問,這塊利用 Nginx 或者 Sentinel 就能實現。
  • 黑名單:對于已知的黃牛 IP 地址或賬戶進行封禁處理,這塊可以直接在 Nginx 上處理,也可以在網關如 Spring Cloud Gateway 上處理。
  • 動態調整:根據系統的實時負載情況動態調整限流閾值。

六 小結

秒殺是一個大工程,以上是松哥和大家分享的一些實現思路,具體落實下來還有很多細節需要處理。

借助本文希望小伙伴們在面試的時候不怯場,能夠回答出來。

責任編輯:武曉燕 來源: 江南一點雨
相關推薦

2021-01-14 05:23:32

高并發消息中間件

2022-09-19 18:14:58

分布式架構中間件

2022-02-17 08:57:18

內存設計進程

2023-08-28 08:52:49

監聽頁面用戶

2024-06-21 08:15:25

2023-09-02 21:22:36

Airbnb系統

2023-01-15 17:57:12

緩存技術kafka磁盤

2021-05-13 07:32:17

培訓代碼同事

2025-04-25 07:15:00

勒索軟件企業安全

2023-12-22 09:03:31

2019-11-27 15:19:44

系統緩存架構

2020-08-03 08:30:00

JSCSS排序

2025-06-10 01:00:00

分布式日志系統

2023-12-29 11:32:27

2023-12-14 17:27:28

架構設計數據表

2023-11-08 07:05:07

架構設計群聊系統

2025-03-17 02:00:00

2025-04-29 02:00:00

高并發系統場景

2025-05-26 01:55:00

HashMap擴容Redis

2015-11-10 10:12:42

重構系統.程序員
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 高清免费av | 国产成人精品一区二区三 | 一区二区三区四区日韩 | 人人爽人人爽人人片av | 成人免费大片黄在线播放 | 日韩三级| 亚州av | 一区二区在线 | 亚洲第一视频网站 | 妞干网视频 | 国产一区二区不卡 | 亚洲精品福利在线 | 免费在线观看一区二区 | 国产精品色哟哟网站 | 欧美精三区欧美精三区 | 久久久久久久久久久丰满 | 日本不卡免费新一二三区 | 拍戏被cao翻了h承欢 | 亚洲免费视频播放 | 欧美黄色大片在线观看 | 精品一区二区三区在线观看国产 | 亚洲九九精品 | 久久久久久久久久久久一区二区 | 欧美日韩综合 | 色就干 | 久久久精品黄色 | 色欧美综合| 久久久黄色 | 蜜臀网 | 成人久久 | 欧美久久久网站 | 九九在线精品视频 | 一二三四在线视频观看社区 | 亚洲成人黄色 | 国产欧美久久精品 | 久久久精品视频免费看 | 欧美 日本 国产 | 日本欧美国产在线观看 | 亚洲天堂久久新 | 天天操天天干天天爽 | 国产婷婷在线视频 |