1. 程式人生 > >利用redis快取解決高併發下後端重複請求措施

利用redis快取解決高併發下後端重複請求措施

   最近在進行壓力測試的時候發現在高併發下,有些介面很可能因為重複請求導致對資料庫操作出來的資料不是你想要的那個樣子。比如,使用者簽到,你只想讓使用者一天簽到一次,為了防止簽到多次,你對於每次強求,都去查詢資料庫今天是不是已經簽到了,如果簽了,就不讓繼續簽到,如果沒簽到,插入簽到資料,更新積分資料什麼的。但是資料庫操作是有時間的,在高併發下這種方式明顯是不能限制重複請求提交的,有可能一個使用者一天簽到好幾次,只要這個提交時間在很短的範圍內就行(親測確實是這樣的)。

     於是就引出了今天要討論的問題,如何處理重複提交的問題。
    首先看看準確的出現重複請求問題的原因(容老夫ctrl+v一段文字):

在業務開發中,我們常會面對防止重複請求的問題。當服務端對於請求的響應涉及資料的修改,或狀態的變更時,可能會造成極大的危害。重複請求的後果在交易系統、售後維權,以及支付系統中尤其嚴重。

前臺操作的抖動,快速操作,網路通訊或者後端響應慢,都會增加後端重複處理的概率。

 前臺操作去抖動和防快速操作的措施,我們首先會想到在前端做一層控制。當前端觸發操作時,或彈出確認介面,或disable入口並倒計時等等,此處不細表。

 但前端的限制僅能解決少部分問題,且不夠徹底,後端自有的防重複處理措施必不可少,義不容辭。 嗯,囉嗦的原因交代完畢,下面來講講具體的solution:   我們說是基於redis快取的處理重複請求的方式,重複請求就是在很短的時間內傳送多次請求,這個時間是相當短的,以至於你進行資料庫查詢來驗證都沒法取阻擋。這樣的話,我們就可以使用一個快取的計數器來阻止這個問題的發生。在介面的開始,定義一個快取計數器(該快取的時間可以是幾秒,幾十秒或者一兩分鐘,能完成短時間內多個請求的這個短時間的時間就行),同一個會員的每個進來一個請求就將這個計數器+1(當然就是用會員的id+一些特定的字串做key),對於大於1的請求不予受理。這樣在這個快取進行的時間段內就能唯一確保只有一個。嗯,具體的實現方式就是這樣。(親測有效)