下列解決方案可以滿足:
等高併發場景。
對於秒殺系統瞬時會有大量使用者湧入,所以在搶購一開始會有很高的瞬間峰值。高峰值流量是壓垮系統很重要的原因,所以如何把瞬間的高流量變成一段時間平穩的流量也是設計秒殺系統很重要的思路。
利用kafka訊息佇列快取使用者請求,後端的秒殺服務再按照自己的速率從訊息佇列拉取請求處理。
邏輯假設庫存是num
;
秒殺服務獲取使用者請求和userid
,先判斷列表order:1
的長度(llen()
)是否超過庫存num
;
如果超過,返回「已經搶光了」;如果沒有超過,則將 useridlpush
到 order:1 列表。
**
<?php
$num = 10; //系統庫存量
$user_id = \session::get('user_id');//當前搶購使用者id
$len = \redis::llen('order:1'); //檢查庫存,order:1 定義為健名
if($len >= $num)
return
'已經搶光了哦';
$result = \redis::lpush('order:1',$user_id); //把搶到的使用者存入到列表中
if($result)
return
'恭喜您!搶到了哦';
超賣問題
在高併發的情況下,假設庫存還剩1個,一定會出現多個執行緒/例項用llen()方法讀取redis的情況,這個時候它們都會認為還有庫存,從而多個userid被新增到列表,也就出現了超賣的bug。
假設庫存是10;
先往goods_store:1列表
中lpush
10個1;
每當獲取乙個使用者請求,先用rpop
從goods_store:1列表
彈出乙個數,然後判斷這個數是否為0;
如果是0,說明庫存已經為空,返回「已經搶光了」,反之,將 useridlpush
到order:1 列表
。 分析
由於redis的所有操作都是原子操作,而且單執行緒的redis保證高併發下的請求都被序列化處理,所以goods_store:1列表
中的10個庫存一定是乙個個序列得被消費。
**
$num=10; //庫存
$len=\redis::llen('goods_store:1'); //檢查庫存,goods_store:1 定義為健名
$count = $num-$len; //實際庫存-被搶購的庫存 = 剩餘可用庫存
for($i=0;$i
\redis::lpush('goods_store:1',1);//往goods_store列表中,未搶購之前這裡應該是預設滴push10個庫存數了
/* 模擬搶購操作,搶購前判斷redis佇列庫存量 */
$count=\redis::lpop('goods_store:1');//lpop是移除並返回列表的第乙個元素。
if(!$count)
return
'已經搶光了哦';
系統再引導下單成功的客戶進入下一步流程。並且系統需要將快取中的資料同步到資料庫對應的表中,比如商品表(改庫存)、訂單表(儲存使用者訂單)。
經過第一步kafka訊息佇列的緩衝,資料庫面臨的壓力是完全可控的,所以使用mysql實現秒殺完全可行。只是在秒殺量比較大的時候,其總體效率肯定是比不上redis的。思路如下:
(1)建立乙個秒殺表 t_flash_sale,使用mysql的自增主鍵特性,設定從1開始自增:
create
table table1(id int auto_increment=1
primary
key,...)
(2)獲取乙個使用者請求則將userid插入 t_flash_sale,獲取返回的插入id;
(3)判斷插入id是否大於庫存num,大於則秒殺失敗。
下單系統面臨的乙個普遍問題:
下一次單需要寫很多資料庫表,而且訂單量比較大,因此使用者的下單速度會比較慢。
解決方案的綱領:將下單邏輯和寫資料庫表的邏輯分開、非同步化。具體架構如下:
使用者層面的訂單是乙個整體,但是訂單中心裡會有很多不同的表,下單一次要更新很多表。
buffer db可以是mysql資料庫,儲存訂單;也可以是訊息佇列。
微信搶紅包架構設計
實時性 為什麼明明搶到紅包,點開後發現沒有?答 2014年的紅包一點開就知道金額,分兩次操作,先搶到金額,然後再轉賬。2015年的紅包的拆和搶是分離的,需要點兩次,因此會出現搶到紅包了,但點開後告知紅包已經被領完的狀況。進入到第乙個頁面不代表搶到,只表示當時紅包還有。分配 紅包裡的金額怎麼算?為什麼...
秒殺架構中高效能可擴充套件高可用的一點思考
1.dns輪詢 秒殺架構作為業界的熱點問題,受到廣泛關注。bat作為業界的翹楚,了解他們的高擴充套件架構對我們的思路也許會有幫助。nslookup用於查詢dns的記錄,查詢網域名稱解析是否正常,在網路故障時用來診斷網路問題,我們先來看看bat的網域名稱解析後是什麼樣子的?紅色方框1中的伺服器,是網域...
可擴充套件的模組化架構的CSS
每個專案需要一些組織。將您建立的每個新風格到單個檔案的結束會發現事情更困難,會對別人非常混亂的專案。當然,你可能有一些組織已經到位。希望你讀在這些頁面將強調與您現有的流程和工作,如果我很幸運,你將會看到新的方法可以改善你的過程。你如何決定是否使用id選擇器,或類選擇器,或任何數量的選擇器在你處理嗎?...