秒殺系統設計中的業務性思考

    秒殺不是一個新鮮事物,特別是過去幾年電商和互金業務的蓬勃發展,各類電商節的興起,促使秒殺已經變成了很是重要的業務功能。我這幾年也沒少和「秒殺」打交道,和團隊共同經歷了各類掙扎後,積累了一些想法,今天想利用這個機會來寫一寫。但今天不是來教你們如何作一個秒殺系統的,而是從業務的角度來思考秒殺系統設計中,咱們須要注意的地方。前端


業務對於秒殺的指望
瀏覽器


既然咱們要從業務的思路上來思考秒殺,那麼咱們就須要明確和轉化,在秒殺場景下,咱們期待的結果是什麼。拋開具體業務,我簡單總結了一下,能夠分爲如下兩點:安全



1)每一個用戶都能參與,可是有且參與一次。微信

2)參與的用戶都是真實有效的。

架構

針對這兩個業務需求,我再來分析一下,要知足這兩個業務需求,咱們的秒殺系統須要具有什麼能力。併發

先說第1點,用技術的語言來翻譯就是:同一個帳戶,不管經過瀏覽器插件或者其餘任何輔助工具發出屢次請求,他最多隻能搶到一次。講到這裏,我必需要多說兩句,這看似是一個簡單的判斷領取邏輯,可是很多團隊在這裏是犯過錯誤的,致使判斷邏輯被繞過,沒有達到去重的效果,以下圖:高併發



先判斷用戶A是否有參與記錄,若是沒有則領取成功,最後將用戶A更新爲已參與記錄中。若是你們仔細想一下,就會發現這裏藏着一個極大的漏洞:在高併發的場景下,在某個請求成功寫入參與記錄的時間段內,用戶A其餘的請求獲查詢到的結果都是「沒有參與記錄」。因此,就存在邏輯判斷被繞過,同一個用戶秒殺成功屢次的狀況出現。工具


正確的作法:插件


秒殺系統只容許接受同一個帳戶的1個請求,其餘請求通通過濾掉。在程序入口加鎖,同一個帳戶,同一時刻只有一個線程在被處理。不只解決了同一個帳號,發送多個請求的問題,還保證了後續的邏輯流程的安全,確保了只有一個線程能更新帳戶的狀態。線程


第1個問題解決後,接下來,咱們須要談一下,怎麼保證秒殺過程當中,用戶的真實性和有效性。

要總結出真實用戶的行爲是比較難的,可是要總結出非真實用戶的行爲相對容易,因此咱們採用反證法的思路,將問題2進行一個拆解,列舉出非真實用戶行爲的表現有哪一些:



  1. IP相對固定(相近IP或者同一IP段),請求的頻率超過正常人的反應速度

  2. 請求的路徑缺少邏輯,不能造成正常的業務鏈路。

  3. User-Agent異常,URL攜帶的參數存在明顯的拼接痕跡。


針對以上幾點非正常狀況,咱們能夠有如下兩種防範措施:


1. 對請求頻率過快的IP進行限制。 能夠在Nginx或者Tengine上執行,詳細信息,能夠參見以前我有關服務端限流的文章

2. 頻率請求過快或者請求頭異常的請求,返回圖形驗證碼到前端(建議不要使用簡單的數字驗證碼),觸發人工解鎖,確保背後是真實的人存在。


進一步思考


實際上,光靠這些技術手段仍是不夠的,由於羊毛黨或者黃牛黨是在不斷進化手段的,人家也肯下血本。因此咱們真要作好秒殺,還須要更多從業務上思考。我在這裏也總結了2點,能夠嘗試:


  1. 分析用戶畫像,根據用戶的活躍度,等級,資料的齊全程度,歷史購買產品,對用戶進行評分,達到特定分數的用戶才能參與秒殺。

  2. 制定業務門檻,好比說,要參與秒殺,對於一個電商平臺,該用戶過去至少有1000元的歷史消費額,對於一個理財平臺,該用戶必需要有訂單在投,等等。


有了這2點,能夠說基本上保證了用戶的真實性,或者說讓造假的動機沒了,保證99%以上的黃牛號或者殭屍號能被過濾掉。


選擇「秒殺券」仍是「秒殺商品」


最後,再想討論一個話題,若是要作一個秒殺系統,是先從秒殺券作起,仍是從秒殺商品開始作起呢?我的建議先經過秒殺券練練手,而後再轉向秒殺商品。緣由很簡單,由於秒殺商品,一下就引入了訂單和支付,庫存的鎖定和釋放,支付的時效等等,涉及到的業務複雜度就高了一個層次。從另一個角度看,秒殺券是和正常的業務流程隔離的,是不會影響到正常的下單流程的。即使是出問題了,作服務降級也會容易許多。


預告一下:明天會講一下商品秒殺系統的落地方案,歡迎圍觀。



掃描二維碼或手動搜索微信公衆號【架構棧】: ForestNotes

歡迎轉載,帶上如下二維碼便可

相關文章
相關標籤/搜索