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


Posted in Redis onFebruary 12, 2022

前言

  主要针对目前线上短信被脚本恶意盗刷的情况,用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滑动窗口限流内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Redis 相关文章推荐
redis 限制内存使用大小的实现
May 08 Redis
Redis高级数据类型Hyperloglog、Bitmap的使用
May 24 Redis
Django使用redis配置缓存的方法
Jun 01 Redis
redis不能访问本机真实ip地址的解决方案
Jul 07 Redis
Redis性能监控的实现
Jul 09 Redis
Redis字典实现、Hash键冲突及渐进式rehash详解
Sep 04 Redis
SpringBoot集成Redis的思路详解
Oct 16 Redis
面试分析分布式架构Redis热点key大Value解决方案
Mar 13 Redis
源码分析Redis中 set 和 sorted set 的使用方法
Mar 22 Redis
redis 解决库存并发问题实现数量控制
Apr 08 Redis
使用Redis实现分布式锁的方法
Jun 16 Redis
聊聊redis-dump工具安装问题
Jan 18 #Redis
redis的list数据类型相关命令介绍及使用
Jan 18 #Redis
关于使用Redisson订阅数问题
Jan 18 #Redis
Redis中缓存穿透/击穿/雪崩问题和解决方法
linux下安装redis图文详细步骤
Springboot/Springcloud项目集成redis进行存取的过程解析
使用RedisTemplat实现简单的分布式锁
Nov 20 #Redis
You might like
jquery方法+js一般方法+js面向对象方法实现拖拽效果
2012/08/30 Javascript
javascript实现炫酷的拖动分页
2015/05/11 Javascript
JavaScript中String.match()方法的使用详解
2015/06/06 Javascript
使用jQuery制作基础的Web图片轮播效果
2016/04/22 Javascript
Nodejs抓取html页面内容(推荐)
2016/08/11 NodeJs
vue select选择框数据变化监听方法
2018/08/24 Javascript
vue中的适配px2rem示例代码
2018/11/19 Javascript
layer.open 获取不到表单信息的解决方法
2019/09/26 Javascript
详解小程序云开发攻略(解决最棘手的问题)
2019/09/30 Javascript
node后端服务保活的实现
2019/11/10 Javascript
原生JS实现汇率转换功能代码实例
2020/05/13 Javascript
js实现随机圆与矩形功能
2020/10/29 Javascript
js正则表达式简单校验方法
2021/01/03 Javascript
python计算圆周长、面积、球体体积并画出圆
2014/04/08 Python
深入源码解析Python中的对象与类型
2015/12/11 Python
Python列表常见操作详解(获取,增加,删除,修改,排序等)
2019/02/18 Python
详解Python 4.0 预计推出的新功能
2019/07/26 Python
基于TensorFlow常量、序列以及随机值生成实例
2020/01/04 Python
Python多线程实现支付模拟请求过程解析
2020/04/21 Python
python3.5的包存放的具体路径
2020/08/16 Python
基于Python组装jmx并调用JMeter实现压力测试
2020/11/03 Python
CSS3教程:background-clip和background-origin
2008/10/17 HTML / CSS
美国独家设计师眼镜在线光学商店:Glasses Gallery
2017/12/28 全球购物
教师自荐书
2013/10/08 职场文书
护士思想汇报
2014/01/12 职场文书
2014教师党员自我评议总结
2014/09/19 职场文书
再婚婚前财产协议书范本
2014/10/19 职场文书
2014年保密工作总结
2014/11/22 职场文书
募捐感谢信
2015/01/22 职场文书
2015年中秋节演讲稿
2015/03/20 职场文书
行政答辩状范文
2015/05/21 职场文书
2019公司管理制度
2019/04/19 职场文书
python制作图形界面的2048游戏, 基于tkinter
2021/04/06 Python
详解Django的MVT设计模式
2021/04/29 Python
Python趣味挑战之用pygame实现简单的金币旋转效果
2021/05/31 Python
vue使用Google Recaptcha验证的实现示例
2021/08/23 Vue.js