基于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通过6379端口无法连接服务器(redis-server.exe闪退)
May 08 Redis
k8s部署redis cluster集群的实现
Jun 24 Redis
Redis做数据持久化的解决方案及底层原理
Jul 15 Redis
Redis中一个String类型引发的惨案
Jul 25 Redis
Redis字典实现、Hash键冲突及渐进式rehash详解
Sep 04 Redis
Redis 持久化 RDB 与 AOF的执行过程
Nov 07 Redis
解决linux下redis数据库overcommit_memory问题
Feb 24 Redis
redis数据一致性的实现示例
Mar 18 Redis
浅谈Redis 中的过期删除策略和内存淘汰机制
Apr 03 Redis
Redis基本数据类型String常用操作命令
Jun 01 Redis
利用Redis实现点赞功能的示例代码
Jun 28 Redis
Redis sentinel哨兵集群的实现步骤
Jul 15 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 文件上传实例代码
2012/04/19 PHP
php中json_decode()和json_encode()的使用方法
2012/06/04 PHP
在win7中搭建Linux+PHP 开发环境
2014/10/08 PHP
Javascript实现的分页函数
2007/02/07 Javascript
理解Javascript_08_函数对象
2010/10/15 Javascript
jquery实现的随机多彩tag标签随机颜色和字号大小效果
2014/03/27 Javascript
JavaScript学习笔记之JS函数
2015/01/22 Javascript
JS实现FLASH幻灯片图片切换效果的方法
2015/03/04 Javascript
原生JS实现九宫格抽奖效果
2017/04/01 Javascript
jquery请求servlet实现ajax异步请求的示例
2017/06/03 jQuery
微信小程序异步处理详解
2017/11/10 Javascript
vue中的计算属性实例详解
2018/09/19 Javascript
JavaScript使用Math.random()生成简单的验证码
2019/01/21 Javascript
python检测远程udp端口是否打开的方法
2015/03/14 Python
Python中利用sqrt()方法进行平方根计算的教程
2015/05/15 Python
Python中将字典转换为XML以及相关的命名空间解析
2015/10/15 Python
Python提取网页中超链接的方法
2016/09/18 Python
Python学习小技巧总结
2018/06/10 Python
实例分析python3实现并发访问水平切分表
2018/09/29 Python
基于python实现名片管理系统
2018/11/30 Python
Python配置虚拟环境图文步骤
2019/05/20 Python
numpy concatenate数组拼接方法示例介绍
2019/05/27 Python
python点击鼠标获取坐标(Graphics)
2019/08/10 Python
python数据类型可变不可变知识点总结
2020/03/06 Python
Python尾递归优化实现代码及原理详解
2020/10/09 Python
Python lxml库的简单介绍及基本使用讲解
2020/12/22 Python
Super-Pharm波兰:药房和香水在一个地方
2020/08/18 全球购物
个人对照检查材料
2014/02/12 职场文书
反邪教宣传工作方案
2014/05/07 职场文书
保护野生动物倡议书
2014/05/16 职场文书
学校标语大全
2014/06/19 职场文书
致800米运动员广播稿(10篇)
2014/10/17 职场文书
工作感想范文
2015/08/07 职场文书
vue完美实现el-table列宽自适应
2021/05/08 Vue.js
python迷宫问题深度优先遍历实例
2021/06/20 Python
springboot+rabbitmq实现智能家居实例详解
2022/07/23 Java/Android