高併發下商城秒殺活動的處理

2021-08-19 04:29:53 字數 1284 閱讀 7364

秒殺搶購活動是現在很多**常見的營銷手段,小公尺搶購、**的整點免單、聚划算等都是成功的例子。

從簡單處著手,秒殺是很好理解的:設定要秒殺的商品的數量,搶完為止。但是,實際應用中一瞬間的高併發壓力、以及併發帶來的負庫存是要著重考慮。

要避免負庫存的出現,可以在資料庫加鎖,不管外部多少請求,都可以在資料庫操作前給阻斷。當然,這種思路可以用在流量不大的普通商品上,用在高併發的秒殺商品上顯然是不合適的,直接高頻率的讀寫運算元據庫,對資料庫的壓力太大,嚴重拖效能,量大的話掛掉也是很有可能的。

這時候就需要用到快取佇列了,現在前面應用層處理併發,這個資源的消耗是比較小的,記憶體中的處理效率也會很快。佇列處理完之後再向資料庫層進行請求操作。

當然,有時候還有可能會用到檔案排他鎖,在處理乙個訂單的時候,使用flock鎖定檔案,如果鎖定失敗說明有其他程序正在鎖檔案處理訂單,返回失敗。但是只使用這個的話,個人感覺不太好,我寧願讓使用者在佇列中多等待幾秒,也不想直接返回失敗。可以在快取佇列到資料庫的時候使用下這個,多加一層安全係數。

模擬場景:

**做乙個秒殺活動,秒殺的商品數量為10,秒到即得。

方案:

1、應用層做首次過濾

因為考慮到處理的失敗,我們要給

快取開的總數比10稍大是最好

的,那我們就給佇列開的總數是50。秒殺開始後,我們的佇列只接收前面50個請求,當數量滿50後,在請求就返回已秒殺完。如果一瞬間的併發大於50,我們就隨機取50個放入佇列。

快取的處理是在記憶體上處理的,效率非常高,但是在這個層面處理過之後要二次請求,可能會有稍許延遲。

2、資料層做二次過濾

從50個中隨機或者排序的方式,二次「併發」按佇列執行下單,這時候可以考慮使用檔案鎖。入庫時也可考慮使用

樂觀鎖、自定義鎖、限制條件等。

經過首次處理後的資料量已經非常小了,直接運算元據庫的話壓力會小很多,二次過濾也能盡可能的保證資料不超出。

其他:

如果是分布式集群伺服器,就需要有乙個或多個多層專門的佇列伺服器,或者配置快取佇列共享。

此方案成立的前提是併發量很大,能接近或者超過放出的數量。如果商品庫存很足,而且併發量不大,反倒影響了使用者體驗。

這種二次過濾的架構,下來之後,能最大限度的保證程式的嚴謹性。

ruesin.com

小公尺和**的搶購還是有稍許不同的,小公尺重在搶的那瞬間,搶到了名額,就是你的,你就可以下單結算。而**則重在付款的時候的過濾,做了多層過濾,比如要賣10件商品,他會讓大於10的使用者搶到,在付款的時候再進行併發過濾,一層層的減少一瞬間的併發量。

高併發下的秒殺 搶東西

這裡以tp框架為例子 這個方法核心就是鎖表和解鎖 這裡鎖定tests表 m execute lock tables tests write data m tests find 1 if data counts 0 m tests where id 1 setdec counts else 操作完之後...

PHP Redis解決高併發下的秒殺(樂觀鎖思路)

搶購 秒殺是平常很常見的場景,面試的時候面試官也經常會問到,比如問你 中的搶購秒殺是怎麼實現的等等。搶購 秒殺實現很簡單,但是有些問題需要解決,主要針對兩個問題 一 高併發對資料庫產生的壓力 二 競爭狀態下如何解決庫存的正確減少 超賣 問題 第乙個問題,對於php來說很簡單,用快取技術就可以緩解資料...

redis實現高併發下的搶購 秒殺功能

常規寫法 查詢出對應商品的庫存,看是否大於0,然後執行生成訂單等操作,但是在判斷庫存是否大於0處,如果在高併發下就會有問題,導致庫存量出現負數 redis的解決方案 1,inlcude oncea include db.php redis new redis resid connect 127.0....