python发送短信每天有限额吗_发送短信如何限制1小时内最多发送11条短信

发送短信如何限制1小时内最多发送11条短信

场景:

发送短信属于付费业务,有时为了防止短信攻击,需要限制发送短信的频率,例如在1个小时之内最多发送11条短信.

如何实现呢?

思路有两个

截至到当前时刻的1个小时之内,看是否有超过11条短信

Date now=new Date();

Date oneHourAgo= //1个小时之前的时刻

//查询条件有两个:时间范围,手机号

List smsList=this.smsService.query(fromTime,toTime,mobile);

if(smsList.size()>11){

System.out.println("超出限制,禁止发送");

}else{

System.out.println("可以发送");

}

dao中:

/***

* 获取指定时间长度(范围)内,发送的短信次数

* 在指定时间长度(范围)内,发送的短信次数是否超出限制

* @param startDate

* @param endDate

* @param mobile

* @return

*/

public Long count(String startDate, String endDate, String mobile) {

CriteriaHelper criteriaHelper = CriteriaHelper.getInstance(this);

return criteriaHelper.between("createTime",startDate,endDate)

.eq("mobile",mobile)

.count();

}

Service中:

/***

* 在指定时间长度(范围)内,发送的短信次数是否超出限制

* @param mobile

* @return

*/

public boolean validateSMSSendCountByTimeRange(String mobile) {

Date now=new Date();

//1小时前的时刻

Date oneHouseAgo = TimeHWUtil.getDateBeforeHour(now, 1);

Long count = this.sMSDao.count(TimeHWUtil.formatDateTime(oneHouseAgo), TimeHWUtil.formatDateTime(now), mobile);

if (count >= SMSUtil.LIMITCOUNT_SEND_SMS) {

String msg="超出限制";

logger.warn(msg);

smsLogger.warn(msg);

return false;

}

return true;

}

最近的11条短信 时间跨度是否小于1小时,如果小于1小时,就禁止发送

每次发送短信,要写入当前时间戳到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=11;

int limitTime=60*60;//1小时,单位:秒

Map map=new HashMap();

map.put("13718486139_1445429819328", "1445431479437");

map.put("13718486139_1445429874699", "1445431485996");

map.put("13718486139_1445429874799", "1445431491527");

map.put("13718486139_1445430757886", "1445431496853");

System.out.println(map);

Listlist=new ArrayList();

for(String key:map.keySet()){

if(key.startsWith(mobile)){

list.add(Long.parseLong(map.get(key))/1000);

}

}

SortListsortUtil=new SortList();

sortUtil.Sort(list, "longValue", "desc");

int length=list.size();

int toIndex=0;//要截取的最大序号

if(limitCount>length){

toIndex=length;

}else{

toIndex=limitCount;

}

Listresult=list.subList(0, toIndex);

long delter=list.get(0).longValue()-list.get(toIndex-1).longValue();

long delterSecond=delter;

System.out.println(delterSecond);

if(delterSecond

System.out.println("超限");

}else{

System.out.println("可以继续发短信");

}

System.out.println(result);

}

步骤:

(1)把当前手机号的所有时间戳放入list中;

(2)对list排序,按时间顺序,从大到小;(时间越大,表示离现在越近)

(3)根据次数(limitCount)限制 来截取list;

(4)计算list中第一个元素和最后一个元素的差量,即limitCount条短信的时间跨度delter

(5)若delter 小于时间限制limitTime,则表示超过限制,那么禁止发送短信

优化之后的代码:

public static boolean isLimit() {

long n = System.currentTimeMillis();

Map records = RedisCacheUtil2.getPushRecordList();

if (ValueWidget.isNullOrEmpty(records)) {

return false;

}

List timestamps = new ArrayList(records.values());

SortList sortUtil = new SortList();

sortUtil.sort(timestamps, null, "desc");

// 1 分钟之内不能超过 4(limitCount)

int limitCount = 4;

int limitTime = 60 * 1000;//1 分钟,单位:豪秒

int length = timestamps.size();

if (length < limitCount) {

//没有超过限制

return false;

}

int toIndex = 0;//要截取的最大序号

/*if (limitCount + 1 > length) {

toIndex = length;

} else {*/

toIndex = limitCount;

// }

List result = timestamps.subList(0, toIndex);

//和当前时间比较

System.out.println("n :" + n);

long delter = /*result.get(0))*/n - Long.parseLong(result.get(toIndex - 1));

long delterSecond = delter;

System.out.println("delter :" + delter);

System.out.println(delterSecond);

if (delterSecond < limitTime) {

System.out.println("record :" + HWJacksonUtils.getJsonP(result));

System.out.println("timestamps :" + HWJacksonUtils.getJsonP(timestamps));

System.out.println("超限");

return true;

} else {

System.out.println("可以继续发短信");

return false;

}

}

使用限流器

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值