暫時不考慮 ip
,什么的限制,只考慮 手機號限制,
如何用redis
做到限制,一個手機號,1分鐘內最多發(fā)一條,一天內最多10條
各位大神有什么好方案,先謝!(崇拜臉)
業(yè)精于勤,荒于嬉;行成于思,毀于隨。
需要兩個緩存
key名稱 phone-busy,緩存1分鐘
key名稱 phone-send-count,緩存1天,每成功發(fā)送一條+1
發(fā)送的時候流程如下:
判斷phone-busy是否存在,存在直接報錯“發(fā)送過快”。
判斷phone-send-count是否存在,存在則繼續(xù)檢測是否等于10,存在且等于10報錯“您今天不能發(fā)送短信了”
發(fā)送短信
寫入phone-busy,有效期1分鐘
寫入phone-send-count+1,有效期當天23:59:59的時間戳-當前時間戳
1分鐘內最多發(fā)一條,用分鐘和手機號為key:min:201701041750:13888888888
一天內最多10條,用日期和手機號號為key: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;
}
大概意思就是這樣了,可以將一分鐘,一天的發(fā)送限制做成配置文件,靈活多變。
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;
}
第一個問題,設置過期時間就可以實現(xiàn)了,只要手機號存在于Redis,就是說明沒到1分鐘
第二個問題,每次發(fā)送的時候更改一下計數(shù)器,將計數(shù)器過期時間設為一天
簡單說明:
你要有兩個key
一個1分鐘過期的key
一個24h過期的key
按照短信業(yè)務來處理,都是按照有效時長,不按照0點結算。