暫時不考慮 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點結算。