使用redis incr處理併發問題
阿新 • • 發佈:2019-02-04
一、背景
最近公司某個簡訊介面因為沒有加驗證碼限制被惡意呼叫,最好的解決辦法是做在傳送簡訊請求前做一個驗證碼驗證通過後再呼叫簡訊介面。但是由於需要立馬改動,藉此使用了一下 “緩兵之計”--redis計數器限制
二、使用redis計數器引入黑名單機制
incr是redis中一個遞增函式手冊是這樣介紹的
Redis Incr 命令將 key 中儲存的數字值增一。
如果 key 不存在,那麼 key 的值會先被初始化為 0 ,然後再執行 INCR 操作。
如果值包含錯誤的型別,或字串型別的值不能表示為數字,那麼返回一個錯誤。
本操作的值限制在 64 位(bit)有符號數字表示之內。
那麼可以通過這個函式,將一分鐘內請求簡訊次數超過3次的手機號拉黑(具體簡訊請求幾次根據具體業務場景確定,我們公司這個業務一分鐘內請求2次簡訊就可以的)
補分程式碼如下,使用expire設定key的生命週期。在expire(多長時間內)這個key被用一次就incr一次。具體上限自己確定
注意:自增函式 ,key為自己定義字串+手機號(方便刪除)
<textarea readonly="readonly" name="code" class="Java"> public Long incr(String key) { Jedis jedis = Redis.Operate.getJedis(); try { return jedis.incr(key); } finally { if (null != jedis) { jedis.close(); } } }
//使用expire設定key的生命週期,(即在多長時間內計數達到上限) public void expire(String key, int seconds) { Jedis jedis = Redis.Operate.getJedis(); try { jedis.expire(key, seconds); } finally { jedis.close(); } }
//最後寫判斷 count 數和最後自增數比較。超了就。。。。你懂得。大體如下 long count = incr(key); if (count == 1) { expire(key,60); } if (count > 1) { //GG,你懂得 return; }