84669 人學習
152542 人學習
20005 人學習
5487 人學習
7821 人學習
359900 人學習
3350 人學習
180660 人學習
48569 人學習
18603 人學習
40936 人學習
1549 人學習
1183 人學習
32909 人學習
暫時不考慮 ip,什麼的限制,只考慮 手機號碼限制,
ip
如何用redis做到限制,一個手機號,1分鐘內最多發一條,一天內最多10條
redis
各位大神有什麼好方案,先謝! (崇拜臉)
业精于勤,荒于嬉;行成于思,毁于随。
需要兩個快取
key名稱 phone-busy,快取1分鐘
key名稱 phone-send-count,快取1天,每成功發送一條+1
發送的時候流程如下:
判斷phone-busy是否存在,存在直接報錯「發送過快」。
判斷phone-send-count是否存在,存在則繼續檢測是否等於10,存在且等於10報錯「您今天不能發送簡訊了」
發送簡訊
寫入phone-busy,有效期限1分鐘
寫入phone-send-count+1,有效期限當天23:59:59的時間戳-當前時間戳
用手機號碼+分鐘,手機號碼+天做為key分別限制一分鐘和一天內發送短信的數量
1分鐘內最多發一條,用分鐘和手機號碼為key:min:201701041750:13888888888一天内最多10条,用日期和手机号号为key:day:20170104:13888888888
min:201701041750:13888888888
day:20170104:13888888888
//php demo function check($phone){ if($redis->exists('min:'.date('YmdHi').':'.$phone) || $redis->get('day:'.date('YmdHi').':'.$phone) > 10){ reutrn false; } $redis->set('min:'.date('YmdHi').':'.$phone,1); $redis->incr('day:'.date('Ymd').':'.$phone); return true; } // 这样按分钟生成的key比较多,可以把手机号对应的分钟放`set`内
寫一段偽代碼如下:
String sendFrequencyKeyPrefix = "send_frequency_"; String dailySendLimitKeyPrefix = "daily_send_limit_"; public function sendMessage(String phoneNumber, String message){ if(redis.get((sendFrequencyKeyPrefix + phoneNumber))) { return false; } int dailySendTotal = int(redis.get((dailySendLimitKeyPrefix + phoneNumber))); if(dailySendTotal >= 10) { return false; } // send message here redis.set((sendFrequencyKeyPrefix + $phoneNumber), "", 60); redis.set((dailySendLimitKeyPrefix + $phoneNumber), dailySendTotal + 1, 3600*24); return true; }
大概意思就是這樣了,可以將一分鐘,一天的發送限製作成配置文件,靈活多變。
1月5日修改;
這裡@Lowky 朋友提醒了一個問題,就是每天這個限制,到底是一天還是24小時,因為這兩個概念是不一樣的。這裡樓主要的應該是每天限制10條,每天凌晨限制放開。每分鐘應該就不考慮這個了。 code修改如下:
String sendFrequencyKeyPrefix = "send_frequency_"; public function sendMessage(String phoneNumber, String message){ String dailySendLimitKeyPrefix = new SimpleDateFormat("yyyy-MM-dd").format(new Date()); if(redis.get((sendFrequencyKeyPrefix + phoneNumber))) { return false; } int dailySendTotal = int(redis.get((dailySendLimitKeyPrefix + phoneNumber))); if(dailySendTotal >= 10) { return false; } // send message here redis.set((sendFrequencyKeyPrefix + $phoneNumber), "", 60); redis.set((dailySendLimitKeyPrefix + $phoneNumber), dailySendTotal + 1, 3600*24); return true; }
第一個問題,設定過期時間就可以實現了,只要手機號碼存在於Redis,就是說明沒到1分鐘第二個問題,每次發送的時候更改一下計數器,將計數器過期時間設為一天
簡單說明:
你要有兩個key
一個1分鐘過期的key
一個24h過期的key
依照簡訊業務來處理,都是依照有效時長,不依照0點結算。
需要兩個快取
key名稱 phone-busy,快取1分鐘
key名稱 phone-send-count,快取1天,每成功發送一條+1
發送的時候流程如下:
判斷phone-busy是否存在,存在直接報錯「發送過快」。
判斷phone-send-count是否存在,存在則繼續檢測是否等於10,存在且等於10報錯「您今天不能發送簡訊了」
發送簡訊
寫入phone-busy,有效期限1分鐘
寫入phone-send-count+1,有效期限當天23:59:59的時間戳-當前時間戳
用手機號碼+分鐘,手機號碼+天做為key分別限制一分鐘和一天內發送短信的數量
1分鐘內最多發一條,用分鐘和手機號碼為key:
min:201701041750:13888888888
一天内最多10条,用日期和手机号号为key:
day:20170104:13888888888
寫一段偽代碼如下:
大概意思就是這樣了,可以將一分鐘,一天的發送限製作成配置文件,靈活多變。
1月5日修改;
這裡@Lowky 朋友提醒了一個問題,就是每天這個限制,到底是一天還是24小時,因為這兩個概念是不一樣的。這裡樓主要的應該是每天限制10條,每天凌晨限制放開。每分鐘應該就不考慮這個了。 code修改如下:
第一個問題,設定過期時間就可以實現了,只要手機號碼存在於Redis,就是說明沒到1分鐘
第二個問題,每次發送的時候更改一下計數器,將計數器過期時間設為一天
簡單說明:
你要有兩個key
一個1分鐘過期的key
一個24h過期的key
依照簡訊業務來處理,都是依照有效時長,不依照0點結算。