秒殺系統設計優化

12306搶票,票是有限的,庫存一份,瞬時流量很是多,都讀相同的庫存,讀寫衝突,鎖很是嚴重;
小米手機每週二的秒殺,可能手機只有1萬部,但瞬時進入的流量多是幾百幾千萬;
這是秒殺業務難的地方。那咱們怎麼優化秒殺系統呢?html

1、難點

(1)高併發
用戶在秒殺開始前,經過不停刷新瀏覽器頁面以保證不會錯過秒殺,這些請求若是按照通常的網站應用架構,訪問應用服務器、鏈接數據庫,會對應用服務器和數據庫服務器形成負載壓力。
(2)超賣
因爲庫存併發更新的問題,致使在實際庫存已經不足的狀況下,庫存依然在減,致使賣家的商品賣得件數超過秒殺的預期。數據庫

2、架構

常見的站點架構基本是這樣的:
(1)瀏覽器端,最上層,會執行到一些JS代碼
(2)站點層,這一層會訪問後端數據,拼HTML頁面返回給瀏覽器
(3)服務層,向上遊屏蔽底層數據細節,提供數據訪問
(4)數據層,最終的庫存是存在這裏的小程序

3、思路

(1)將請求儘可能攔截在上游:傳統秒殺系統之因此掛,請求都壓倒了後端數據層,數據庫讀寫鎖衝突嚴重,致使響應慢,下單基本不能成功
(2)利用緩存:這是一個典型的讀多些少的應用場景,很是適合使用緩存後端

4、解決方案

(1)瀏覽器層請求攔截
1.產品層面,用戶點擊「查詢」或「購票」後,按鈕置灰,禁止用戶重複提交請求
2.js層面,限制用戶在n秒以內只能提交一次請求
(2)站點層請求攔截與頁面緩存
1.靜態化,將活動頁面上的全部能夠靜態的元素所有靜態化,並儘可能減小動態元素
2.限頻率,同一個UID,限制訪問頻率,作頁面緩存,n秒內到達站點層的請求,均返回同一頁面
(3)服務層請求攔截與數據緩存
1.對於寫請求,將全部寫請求在緩存(Redis或Memcached)中,作請求單隊列排隊,每次只透過有限的寫請求異步寫入到數據層,若是均成功再放下一批,若是庫存不夠則隊列裏的寫請求所有返回「已售完」
2.對於讀請求,用Redis或Memcached
緩存寫性能和讀性能都遠高於MySQL,只有很是少的寫和讀緩存的請求會透到數據層去
(4)數據層
1.嘗試扣減庫存,扣減庫存成功纔會進行下單邏輯(因爲MySQL事務的特性,不可能徹底避免超賣)微信小程序

UPDATE table_name SET n=n-1 WHERE n>1;

2.扣減庫存後進行檢查,保證減完不能等於負數
查看更多:
開發一個微信小程序實例教程
HTTP協議整理
PHP安全之Web攻擊
MySQL優化
Linux下常見的IO模型

參考資料:
https://my.oschina.net/xianggao/blog/524943
http://www.infoq.com/cn/articles/flash-deal-architecture-optimization瀏覽器

相關文章
相關標籤/搜索