iis服务器助手广告
返回顶部
首页 > 资讯 > 后端开发 > 其他教程 >基于Redis zSet实现滑动窗口对短信进行防刷限流的问题
  • 507
分享到

基于Redis zSet实现滑动窗口对短信进行防刷限流的问题

2024-04-02 19:04:59 507人浏览 薄情痞子
摘要

前言   主要针对目前线上短信被脚本恶意盗刷的情况,用Redis实现滑动窗口限流 public void checkCurrentWindowValue(String telNum)

前言

  主要针对目前线上短信被脚本恶意盗刷的情况,用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

//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滑动窗口限流内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: 基于Redis zSet实现滑动窗口对短信进行防刷限流的问题

本文链接: https://www.lsjlt.com/news/138540.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • 基于Redis zSet实现滑动窗口对短信进行防刷限流的问题
    前言   主要针对目前线上短信被脚本恶意盗刷的情况,用Redis实现滑动窗口限流 public void checkCurrentWindowValue(String telNum)...
    99+
    2024-04-02
  • redis zset实现滑动窗口限流的代码
    目录限流redis zset特性滑动窗口算法java代码实现补充:Redis zSet实现滑动窗口对短信进行防刷限流前言示例代码限流 需求背景:同一用户1分钟内登录失败次数超过3次,...
    99+
    2024-04-02
  • ASP.NET Core基于滑动窗口实现限流控制的方法
    今天小编给大家分享一下ASP.NET Core基于滑动窗口实现限流控制的方法的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解...
    99+
    2023-06-29
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作