前言
主要针对目前线上短信被脚本恶意盗刷的情况,用redis实现滑动窗口限流
public void checkcurrentwindowvalue(string telnum) {
string windowkey = commonconstant.getnnsmswindowkey(telnum);
//获取当前时间戳
long currenttime = system.currenttimemillis();
//1小时,默认只能发5次,参数smswindowmax做成可配置项,配置到nacos配置中心,可以动态调整
if (redisutil.haskey(windowkey)) {
//参数smswindowtime表示限制的窗口时间
//这里获取当前时间与限制窗口时间之间的短信发送次数
optional<long> optional = optional.ofnullable(redisutil.zcount(windowkey, currenttime - smswindowtime, currenttime));
if (optional.ispresent()) {
long count = optional.get();
if (count >= smswindowmax) {
log.error("==========>当前号码:{} 短信发送太频繁,{}", telnum, count);
throw new serviceexception(midretcode.umid_10060);
}
}
}
stringbuilder sb =new stringbuilder();
string windowele = sb.append(telnum).append(":").append(currenttime).tostring();
//添加当前发送元素到zset中(由于保证元素唯一,这里将元素加上了当前时间戳)
redisutil.zadd(windowkey, windowele, currenttime);
//设置2倍窗口key:windowkey 的过期时间
redisutil.expire(windowkey, smswindowtime*2, timeunit.milliseconds);
}
补充:下面看下以php语言为例基于redis实现滑动窗口式的短信发送接口限流
滑动窗口短信发送限流算法
1.有两条规则
基于ip的限制和基于手机号的限制
ip规则:
1分钟限制5
10分钟限制30
1小时限制50
手机号规则:
1分钟限制1
10分钟限制5
1小时限制10
2.滑动窗口就是随着时间的流动 , 进行动态的删减区间内的数据 , 限制时获取区间内的数据
最主要的是用到了redis的zremrangebyscore来进行删除区间外的数据
<?php
/*滑动窗口短信发送限流算法
1.有两条规则
基于ip的限制和基于手机号的限制
ip规则:
1分钟限制5
10分钟限制30
1小时限制50
手机号规则:
1分钟限制1
10分钟限制5
1小时限制10
*/
//ip规则
$iprules=array(
60=>5,
600=>30,
3600=>50
);
//手机号规则
$phonerules=array(
60=>1,
600=>5,
3600=>10
);
$r = checklimits($iprules,$_server["remote_addr"],$_get['tel']);
var_dump($r);
$r = checklimits($phonerules,$_get['tel'],$_get['tel']);
var_dump($r);
function checklimits($rules,$key,$tel){
$redis = new redis();
$redis->connect('115.159.28.111', 1991);
foreach($rules as $ruletime=>$rule) {
$rediskey=$key."_".$ruletime;
$score=time();
$member=$tel.'_'.$score;
$redis->multi();
$redis->zremrangebyscore($rediskey, 0, $score - $ruletime);//移除窗口以外的数据
$redis->zadd($rediskey, $score, $member);
$redis->expire($rediskey, $ruletime);
$redis->zrange($rediskey, 0, -1, true);
$members = $redis->exec();
if (empty($members[3])) {
break;
}
$nums=count($members[3]);
var_dump($nums);
if($nums>$rule){
return false;
}
}
return true;
}
到此这篇关于基于redis zset实现滑动窗口对短信进行防刷限流的文章就介绍到这了,更多相关redis zset滑动窗口限流内容请搜索www.887551.com以前的文章或继续浏览下面的相关文章希望大家以后多多支持www.887551.com!