使用Redis計數器防止併發請求

2021-09-21 00:13:25 字數 1386 閱讀 5583

最近專案中有個需求,簡訊傳送的併發請求問題:業務需求是需要限制乙個號碼一分鐘內只能獲取一次隨機碼,之前的實現是簡訊傳送請求過來後,先去資料庫查詢傳送記錄,根據上一次的簡訊傳送時間和當前時間比較,如果時間差小於一分鐘,則提示簡訊獲取頻繁,如果超過一分鐘,則傳送簡訊,並記錄簡訊傳送日誌。

簡訊傳送是乙個很敏感的業務,上面的實現存在乙個併發請求的問題,當同一時間有很多請求過來時,同時去查庫,同時獲取到上一次傳送時間沒有,或者已超過一分鐘,這時候就會重**送簡訊了。

redis incr 可以實現原子性的遞增,可應用於高併發的秒殺活動、分布式序列號生成等場景。這裡我使用它來計數實現一分鐘內只接受一次請求。

實現邏輯也很簡單:我們在接到簡訊傳送請求後,使用redis的incr設定乙個遞增key(key由固定字串+手機號碼組成),並判斷該key的數值,如果等於1,說明是第乙個請求,我們將該key值有效期設定為一分鐘;如果該key的數值大於1,說明是1分鐘內的多次請求,這時我們直接返回簡訊獲取頻繁,**如下:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

string rediskey =

"sms_limit_" + smsphone;

long count = redistemplate.opsforvalue().increment(rediskey,

1);if (count ==

1) if (count >

1) /** 傳送簡訊 */

......

/** 記錄傳送日誌 */

......

使用jmeter進行併發測試,同時傳送200個執行緒請求,通過測試發現可避免併發請求問題 :

檢視結果,只有第乙個請求傳送了簡訊,剩餘199個請求均返回失敗:

可以看出效能還是很不錯的:

利用Redis實現高併發計數器

業務需求中經常有需要用到計數器的場景 譬如乙個手機號一天限制傳送5條簡訊 乙個介面一分鐘限制多少請求 乙個介面一天限制呼叫多少次等等。使用redis的incr自增命令可以輕鬆實現以上需求。以乙個介面一天限制呼叫次數為例 是否拒絕服務 return private boolean denialofse...

redis作為計數器的使用

剛剛入行的小白,什麼都不太懂,最近某活動要求獎品領取量上限為20萬,就想到用redis來實現,如下 片段 string rediskey activity redisutil.setstring keystring,0 初始值為0 int countnum 0 每月限量20萬,所以每次使用者進來都更...

Redis計數器實現併發控制,介面限流

redis incr 可以實現原子性的遞增,可應用於高併發的秒殺活動 分布式序列號生成等場景。這裡我使用它來計數實現一分鐘內只接受一次請求。實現邏輯也很簡單 我們在接到簡訊傳送請求後,使用redis的incr設定乙個遞增key key由固定字串 手機號碼組成 並判斷該key的數值,如果等於1,說明是...