本文結構很簡單:git
5張圖送你5種秒殺系統,再加點騷操做,再順帶些點內心話🤷♀️。
實現原理: 經過redis原子操做減庫存github
圖一
redis
優勢 | 缺點 |
---|---|
簡單好用 | 考驗redis服務能力 |
是否公平 |
---|
公平 |
先到先得 |
咱們稱這類秒殺系統爲:算法
簡單秒殺系統
若是剛開始QPS並不高,redis徹底抗的下來的狀況,徹底能夠依賴這個「簡單秒殺系統」。segmentfault
實現原理: 服務內存限流算法 + redis原子操做減庫存api
圖二運維
優勢 | 缺點 |
---|---|
簡單好用 | - |
是否公平 |
---|
不是很公平 |
相對的先到先得 |
咱們稱這類秒殺系統爲:性能
夠用秒殺系統
實現原理: 服務本地內存原子操做減庫存優化
服務本地內存的庫存怎麼來的?
活動開始前分配好每臺機器的庫存,推送到機器上。spa
圖三
優勢 | 缺點 |
---|---|
高性能 | 不支持動態伸縮容(活動進行期間),由於庫存是活動開始前分配好的 |
釋放redis壓力 | - |
是否公平 |
---|
不是很公平 |
不是絕對的先到先得 |
咱們稱這類秒殺系統爲:
預備庫存秒殺系統
實現原理: 服務本地協程Coroutine定時redis原子操做減部分庫存到本地內存 + 服務本地內存原子操做減庫存
圖四
優勢 | 缺點 |
---|---|
高性能 | 支持動態伸縮容(活動進行期間) |
釋放redis壓力 | - |
具有通用性 | - |
是否公平 |
---|
不是很公平,可是好了點 |
幾乎先到先得 |
咱們稱這類秒殺系統爲:
實時預備庫存秒殺系統
實現原理: 服務本地Goroutine定時同步是否售罄到本地內存 + 隊列 + 排隊成功輪訓(或主動Push)結果
圖五
優勢 | 缺點 |
---|---|
高性能 | 開發成本高(需主動通知或輪訓排隊結果) |
真公平 | - |
具有通用性 | - |
是否公平 |
---|
很公平 |
絕對的先到先得 |
咱們稱這類秒殺系統爲:
公平排隊秒殺系統
上面的秒殺系統還不夠完美嗎?
答案:是的。
還有什麼優化的空間?
答案:靜態化獲取秒殺活動信息的接口。
靜態化是什麼意思?
答案:好比獲取秒殺活動信息是經過接口 https://seckill.skrshop.tech/v1/acticity/get
獲取的。如今呢,咱們須要經過https://static-api.skrshop.tech/seckill/v1/acticity/get
這個接口獲取。有什麼區別呢?看下面:
服務名 | 接口 | 數據存儲位置 |
---|---|---|
秒殺服務 | https://seckill.skrshop.tech/... | 秒殺服務內存或redis等 |
接口靜態化服務 | https://static-api.skrshop.te... | CDN、本地文件 |
之前是這樣
變成了這樣
結果:能夠經過接口https://static-api.skrshop.tech/seckill/v1/acticity/get
就獲取到了秒殺活動信息,流量都分攤到了cdn,秒殺服務自身沒了這部分的負載。
小聲點說:「秒殺結果我也敢推CDN😏😏😏。」
備註: 以後咱們會分享`如何用Golang設計一個好用的「接口靜態化服務」`。
上面咱們獲得了以下幾類秒殺系統
秒殺系統 |
---|
簡單秒殺系統 |
夠用秒殺系統 |
預備庫存秒殺系統 |
實時預備庫存秒殺系統 |
公平排隊秒殺系統 |
我想說的是裏面沒有最好的方案,也沒有最壞的方案,只有適合你的。
拿先到先得
來講,必定要看大家的產品對外宣傳,切勿上來就追逐絕對的先到先得。其實你看全部的方案,相對而言都是「先到先得」,好比,活動開始一個小時了你再來搶,那相對於準時的用戶天然搶不過,對吧。
又如預備庫存秒殺系統
,雖然不支持動態伸縮容。可是若是你的環境知足以下任意條件,就徹底夠用了。
秒殺場景結束時間之快,一般幾秒就結束了,真實活動可能會發生以下狀況:
因此:
合適好用就行,切勿過分設計。
此次算是把老本都吐露出來了,真是慌得一匹。
SkrShop歷史分享:https://github.com/skr-shop/m...