秒殺項目的思考

我再刷面經的時候看到好多對於秒殺系統的問題,自己就搗鼓了一個。

思路圖

我們就從最差的情況一步一步解決。

1.數據庫直接被穿?

當我們秒殺系統的數據庫被打穿以後,我們一定不要影響到其他系統。將秒殺系統數據庫獨立出來。

不然你的業務不僅不行,還把其他人搞砸了,你要被祭天了。

2.我們怎麼防止我們數據庫被打穿?

數據庫扛不住,就用它兄弟redis來抗,一個扛不住,咱們就加集羣,加主從,加哨兵無腦高可用。

3.那怎麼讓我們系統處理的併發量少點呢(限流)?

我們可以把請求全部放到mq中,這樣達到了削峯的目的,減輕了下游的併發量。

4.消費者是用來做業務邏輯的,我們儘量不要打崩到這一層

我們把發送者和消費者分成兩個系統,最多把發送者打崩,不能影響到mq和消費者。

5.但是我們也不能這麼輕易的讓他把發送方打壞?

我們可以通過nginx+集羣來提高併發量。

6.我們可不可以在前端就限制一部分?

我們可以把那個按鈕他連着按幾次就給他整灰了,讓他那麼頻繁的請求。

7.我們可不可以在nginx中先限制一部分呢?

我們可以在nginx把那些機器人或者代理服務器給他屏蔽掉。

 

好了屁話說完了,開始正經說。

首先我們在nginx中通過限制user-agent來限制一些看起來就不是正常人的用戶瀏覽器,然後看看日誌找出惡意ip。

然後進入前端,這時候我們在秒殺前保持按鈕是灰色的,等到時間到了以後才能打開。並且可以當收到庫存不足的響應以後直接把按鈕去掉,提示用戶已經賣完了。

然後請求就可發送方這裏了,我們接收到請求,把請求進行解析好,存到mq中去,這塊可能會有一個丟數據的可能,應該可以通過分佈式事務解決(還沒來的及看),這樣我們的請求就到了mq中。

到了mq中,我們的mq是有掛掉的可能的,那我們持久化????

當然不能這樣做,mq是內存中的,如果我們持久化的跟直接寫磁盤有什麼區別呢?我們要配置主從同步,並且哨兵機制那種思想也可以用在這裏。

可能有小夥伴就問了,問什麼你redis中 就 用持久化呢?

因爲redis的數據是主要用來讀取的,不是頻繁寫入和刪除的。

言歸正傳,下面消費者開始讀取mq中數據,因爲mq中確保了消費(返回給他ack標誌)所以不會發生丟數據的情況。

然後消費者拿到了請求,首先先去redis中看看庫存量是不是還有,如果有的話,那麼減一然後進入下游。

那麼這裏就可能會發生超賣的問題,我的思路是通過分佈式鎖來保證不會發生超賣(歡迎大佬提新的思路)。

那如果我要的商品沒有在redis中裏邊呢?那麼就直接打通db,開啓事務去減減,這樣如果你的商品是熱點數據沒有在裏邊這樣是有問題的(打崩數據庫的風險),其實我們可以把讀redis的鎖直作爲操作數據庫的鎖。

下邊就是生成訂單開啓支付這一系列的功能了。

細心的朋友可能發現我少說了一個問題,那就是我怎麼保證我redis中的數據都是熱點數據?這個還請觀衆老爺們給點建議。

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章