使用redis进行用户接口访问时间次数限制

2023-10-27

使用redis进行用户接口访问时间次数限制

假设一个用户(用IP判断)每分钟访问某一个服务接口的次数不能超过10次

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.Response;
import redis.clients.jedis.Transaction;


/**
 * 
 * <p>Title:</p>
 */
public class RateLimit {



private static final Logger logger = LogUtil.get();

private static final String RATE_LIMIT = "RATELIMIT";

/** 
     * @Title: allow @Description: 进行流量控制,允许访问返回true 不允许访问返回false  
     * @param: @param key 放入redis的key,放入前要在key之前添加前缀 前缀配置在eds.properties中的 redis.prefix 
     * @param: @param timeOut 超时时间单位秒 
     * @param: @param count 超时时间内允许访问的次数 
     * @param: @param type 不同类型的数据
     * @param: @return 
     * @param: @throws 
     *             Exception @return: boolean @throws 
     */  
    public static boolean allow(String type,String key, int timeOut, int count) {  
  
//        Boolean useFc = Boolean.valueOf(EdsPropertiesUtil.getInstance().getProperty("flowControl.use"));  
//        // 若不使用流量控制直接返回true  
//        if (!useFc) {  
//            return true;  
//        }  
  
        boolean result = false;  
        Jedis jedis = null;  
        StringBuffer keyBuff = new StringBuffer(RATE_LIMIT);
        keyBuff.append("_").append(type).append(":").append(key);
        key = keyBuff.toString();
        try {  
        jedis = new Jedis(ConfigurationUtil.getRedisHost(), Integer.valueOf(ConfigurationUtil.getRedisPort()));
    if (StringUtils.isNoneEmpty(ConfigurationUtil.getRedisPassWord())) {
    jedis.auth(ConfigurationUtil.getRedisPassWord());
    }
    jedis.connect();
            Long newTimes = null;  
            Long pttl = jedis.pttl(key);  
  
            if (pttl > 0) {  
                newTimes = jedis.incr(key);  
                if (newTimes > count) {  
                    logger.info("key:{},超出{}秒内允许访问{}次的限制,这是第{}次访问", new Object[] { key, timeOut, count, newTimes });  
                } else {  
                    result = true;  
                }  
            } else if (pttl == -1 || pttl == -2 || pttl == 0) {  
  
                Transaction tx = jedis.multi();  
                Response<Long> rsp1 = tx.incr(key);  
                tx.expire(key, timeOut);  
                tx.exec();  
                newTimes = rsp1.get();  
                if (newTimes > count) {  
                    logger.info("key:{},{}秒内允许访问{}次,第{}次访问", new Object[] { key, timeOut, count, newTimes });  
                } else {  
  
                    result = true;  
                }  
  
            }  
            if (result) {  
                logger.debug("key:{},访问次数{}", new Object[] { key, newTimes });  
            }  
  
        } catch (Exception e) {  
            logger.error("流量控制发生异常", e);  
            e.printStackTrace();  
            // 当发生异常时 允许访问  
            result = true;  
        } finally {  
            jedis.close();  
        }  
  
        return result;  
  
    }  
}

ConfigurationUtil 为配置文件中的值

 

 

方法调用:

// 限制器,限制在60秒之内最多登录5次

if (RateLimit.allow("RECOMMENDCODE",accountCode, 60, 5)) {
             //处理业务
        }else{
   //返回失败
       }

 

 

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用redis进行用户接口访问时间次数限制 的相关文章

随机推荐

  • 序列检测器

    序列检测器 目标检测连续的三个1 6 6 4章节 第一种方法是采用状态机 第二种方法是用移位寄存器来存储输入值 并检测寄存器的值是否和预设的序列相匹配
  • Linux系统gdb调试常用命令

    GDB GNU调试器 是一款常用的调试工具 用于调试C C 等编程语言的程序 以下是一些常用的GDB命令 1 启动程序 gdb
  • jQuery笔记 (完整详细版)

    2018 9 17 星期一 jQuery 第一章 初识jQuery 第二章 jQuery的事件和API 第三章 jQuery中的动画 第一章 初识jQuery 一 jQuery简介 1 什么是jQuery jQuery是一个优秀的JavaS
  • VUE高德地图实现根据移动覆盖点获得经纬度坐标和详细地址及根据经纬度确定覆盖点

    经纬度手动定位 输入经纬度 显示详细地址 async handleMapPositioning const result await this api getProductLocation this unionId this reMap n
  • C++类

    一个简单的类 定义一个类 class MyClass 类名 public 访问修饰符 MyClass 构造函数 MyClass 析构函数 void function 成员函数 也叫成员方法 private int m data 成员数据 不
  • C++ 计算代码运行时间

    在算法比较中 耗时是一个重要的指标 每次都要去搜别人的博客 今天摘抄一下askunix hjh的博客 感谢博主 原文记录了三种办法 我选择了其中比较易懂的 GetTickCount是函数 GetTickCount返回 retrieve 从操
  • k8s部署Dashboard可视化插件

    DashBoard可视化插件 可以给用户提供一个可视化的Web界面来查看当前集群的各种信息 一 下载Dashboard所需的yaml文件 wget https raw githubusercontent com kubernetes das
  • 关闭虚拟机的防火墙

    CentOS6 切换至root用户 然后输入 service iptables stop 命令即可关闭防火墙 CentOS7 切换至root用户 先输入 systemctl stop firewalld 命令关闭防火墙 然后输入 syste
  • dataclass的作用

    dataclasss的作用 from dataclasses import dataclass dataclass class Person name str age int gender str unknown init 方法用于初始化对
  • HTML转义字符大全

    1 常用转义字符 转义字符串 Escape Sequence 也称字符实体 Character Entity 在HTML中 定义转义字符串的原因有两个 第一个原因是像 lt 和 gt 这类符号已经用来表示HTML标签 因此就不能直接当作文本
  • 学习 bison 原理(四)

    2019独角兽企业重金招聘Python工程师标准 gt gt gt 学习 bison 原理 四 第5步 转变第 4 步的状态机为确定的 LALR 状态机 在 三 中我们已经看到 LR0 状态机很可能有 r r 冲突 s r 冲突 那这关键的
  • QList与QVector

    看qt的文档 只要是不要求数据所存放的内存是连续的 都建议用QList 因为QList的查询速度跟QVecotr是差不多的 感觉有点奇怪 至少与我之前所认识的List的查询是一不样的 好吧 看看源码的 原来QList的元素的指针是通过数组来
  • 文本处理——基于 word2vec 和 CNN 的文本分类 :综述 & 实践(一)

    原文地址 https zhuanlan zhihu com p 29076736 导语 传统的向量空间模型 VSM 假设特征项之间相互独立 这与实际情况是不相符的 为了解决这个问题 可以采用文本的分布式表示方式 例如 word embedd
  • ohmyzsh主题修改

    1 选择主题 ohmyzsh Themes by Github 2 修改zsh配置 vim zshrc 3 使配置生效 source zshrc 效果如下
  • 二、初识arduino uno开发板

    开发板参数表 什么是arduino Arduino是一款便捷灵活 方便上手的开源电子原型平台 包含硬件 各种型号的Arduino板 和软件 ArduinoIDE 构建于开放原始码simple I O介面版 并且具有使用类似Java C语言的
  • Golang闭包陷阱

    golang闭包陷阱本质原理其实是range陷阱 Golang for range陷阱 ep 1 func main var values int 1 2 3 4 5 for value range values go func fmt P
  • 编译 OneFlow 模型

    本篇文章译自英文文档 Compile OneFlow Models tvm 0 14 dev0 documentation 作者是 BBuf Xiaoyu Zhang GitHub 更多 TVM 中文文档可访问 Apache TVM 是一个
  • 3月6日服务器例行维护公告,2014年3月6日停机维护公告

    亲爱的玩家 为了保证服务器的稳定和服务质量 新大话西游2 将于2014年3月6日早上8 00停机 进行每周例行的维护工作 维护时间为早上08 00至09 30 同时 本次停机还将发布最新的客户端补丁 patch2 0 476 如果在维护期间
  • Java高级编程——多线程(JDK5新增创建线程方式Callable,线程池)

    创建线程的第三 四种方式 一 实现Callable接口 1 1与Runnable相比 1 2实现步骤 创建Callable接口实现类 重写call方法 新建实现类对象 将实现类对象作为参数传递待FutureTask的构造器中 创建Futur
  • 使用redis进行用户接口访问时间次数限制

    使用redis进行用户接口访问时间次数限制 假设一个用户 用IP判断 每分钟访问某一个服务接口的次数不能超过10次 import org apache commons lang3 StringUtils import org slf4j L