判斷一個小時之内是否重複發送了10次短信
并且是同一個手機
每次發送短信,要寫入目前時間戳到redis:
string mobile="13718486139";
string time=string.valueof(datetimeutil.getcurrentmillisecond());
redishelper.getinstance().savekeycache("limit_one_hour", mobile+"_"+time, time);
檢查時先擷取所有時間戳:
map map=redishelper.getinstance().getallkeycache("limit_one_hour");
具體判斷邏輯:
@test
public void test_limitonehour2(){
string mobile="13718486139";
int limitcount=5;
int limittime=2*60;//兩分鐘
map<string,string> map=new hashmap<string,string>();
map.put("13718486139_1445429819328", "1445431479437");
map.put("13718486139_1445429874699", "1445431485996");
map.put("13718486139_1445429874799", "1445431491527");
map.put("13718486139_1445430757886", "1445431496853");
system.out.println(map);
list<long>list=new arraylist<long>();
for(string key:map.keyset()){
if(key.startswith(mobile)){
list.add(long.parselong(map.get(key))/1000);
}
}
sortlist<long>sortutil=new sortlist<long>();
sortutil.sort(list, "longvalue", "desc");
int length=list.size();
int toindex=0;//要截取的最大序号
if(limitcount>length){
toindex=length;
}else{
toindex=limitcount;
list<long>result=list.sublist(0, toindex);
long delter=list.get(0).longvalue()-list.get(toindex-1).longvalue();
long deltersecond=delter;
system.out.println(deltersecond);
if(deltersecond<limittime){
system.out.println("超限");
system.out.println("可以繼續發短信");
system.out.println(result);
}
步驟:
(1)把目前手機号的所有時間戳放入list中;
(2)對list排序,按時間順序,從大到小;(時間越大,表示離現在越近)
(3)根據次數(limitcount)限制 來截取list;
(4)計算list中第一個元素和最後一個元素的差量,即limitcount條短信的時間跨度delter
(5)若delter 小于時間限制limittime,則表示超過限制,那麼禁止發送短信
問題
為什麼要以這種方式存儲到redis?
"limit_one_hour" "13718486139_1445429819328" "1445431496853"
而不是直接以手機号為key
13718486139 "1445431496853" ""
因為:可能其他redis項是以手機号為key的,這樣就會覆寫掉.即這樣做有風險.
不過如下方式可以:
13718486139_limit_one_hour "1445431496853" ""