基于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配置文件中常用配置详解
Apr 14 Redis
解析Redis Cluster原理
Jun 21 Redis
Redis 彻底禁用RDB持久化操作
Jul 09 Redis
Redis Cluster集群动态扩容的实现
Jul 15 Redis
嵌入式Redis服务器在Spring Boot测试中的使用教程
Jul 21 Redis
Redis中一个String类型引发的惨案
Jul 25 Redis
Redis分布式锁Redlock的实现
Aug 07 Redis
基于Redis结合SpringBoot的秒杀案例详解
Oct 05 Redis
Redis模仿手机验证码发送的实现示例
Nov 02 Redis
Redis集群节点通信过程/原理流程分析
Mar 18 Redis
redis sentinel监控高可用集群实现的配置步骤
Apr 01 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
通过PHP CLI实现简单的数据库实时监控调度
2009/07/01 PHP
Php获取金书网的书名的实现代码
2010/06/11 PHP
PHP回调函数与匿名函数实例详解
2017/08/16 PHP
php 后端实现JWT认证方法示例
2018/09/04 PHP
详细讲解JS节点知识
2010/01/31 Javascript
JS俄罗斯方块,包含完整的设计理念
2010/12/11 Javascript
js中iframe调用父页面的方法
2014/10/30 Javascript
js实现倒计时及时间对象
2016/11/15 Javascript
详谈js中window.location.search的用法和作用
2017/02/13 Javascript
详解AngularJS 模块化
2017/06/14 Javascript
JavaScript之Map和Set_动力节点Java学院整理
2017/06/29 Javascript
vue.js项目 el-input 组件 监听回车键实现搜索功能示例
2018/08/25 Javascript
详解在vue-cli中使用graphql即vue-apollo的用法
2018/09/08 Javascript
微信小程序实现定位及到指定位置导航的示例代码
2019/08/20 Javascript
Vue+elementUI实现多图片上传与回显功能(含回显后继续上传或删除)
2020/03/23 Javascript
vue iview 隐藏Table组件里的某一列操作
2020/11/13 Javascript
实例讲解Python编程中@property装饰器的用法
2016/06/20 Python
python命令行解析之parse_known_args()函数和parse_args()使用区别介绍
2018/01/24 Python
Python常见排序操作示例【字典、列表、指定元素等】
2018/08/15 Python
Opencv+Python 色彩通道拆分及合并的示例
2018/12/08 Python
如何使用Python处理HDF格式数据及可视化问题
2020/06/24 Python
Mytheresa英国官网:拥有160多个奢侈品品牌
2016/10/09 全球购物
会计电算化专业毕业生求职信范文
2013/12/10 职场文书
酒店门卫岗位职责
2013/12/29 职场文书
宿舍违规用电检讨书
2014/02/16 职场文书
大学生职业生涯规划书参考模板
2014/03/05 职场文书
保护环境倡议书500字
2014/05/19 职场文书
大学生实习证明范本
2014/09/19 职场文书
企业2014年度工作总结
2014/12/10 职场文书
高中英语教学反思范文
2016/03/02 职场文书
简历中的自我评价怎么写呢?
2019/04/30 职场文书
决心书格式及范文
2019/06/24 职场文书
一些让Python代码简洁的实用技巧总结
2021/08/23 Python
python编程项目中线上问题排查与解决
2021/11/01 Python
Windows11插耳机没反应怎么办? win11耳机没声音的多种解决办法
2021/11/21 数码科技
Golang jwt身份认证
2022/04/20 Golang