Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >单个用户及Ip请求频率限制思路(附java实现)

单个用户及Ip请求频率限制思路(附java实现)

作者头像
vakinge
发布于 2023-02-22 07:21:31
发布于 2023-02-22 07:21:31
1.4K00
代码可运行
举报
文章被收录于专栏:伯约架构思维伯约架构思维
运行总次数:0
代码可运行

我们熟悉的限流算法漏桶和令牌桶外,很多情况我们还需要考虑当个用户(ip)访问频率控制,避免被恶意调用。如果是开放平台限制一天调用多少次这种粗放的粒度相对好处理一些。如果需要更小时间粒度控制,譬如一个10秒时间窗口最大只允许访问10次,相对上述粗放粒度我们还需要考虑性能和边界两个问题。在这里提供一种思路给大家,这个也是我写的api网关访问频率控制的代码,经过了线上环境实践。

推荐:,jeesuite开发框架免费开源、一站式解决方案。


思路(以10秒限制10次为例)

定义一个全局map

key为用户标识(ip or sessionId),

value:List<10秒内访问时间戳>

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
private Map<String, List<Long>> accessDatas = new ConcurrentHashMap<>();

启动一个定时器,用于清除10秒前的访问时间

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
cleanScheduledExecutor.scheduleAtFixedRate(new Runnable() {
        @Override 
        public void run() {
          long currentTime = System.currentTimeMillis();

          List < Long > accessPoints = null;
          Iterator < String > idsIterator;
          if (gloabalScanFlag == 5) {
            //清理空记录
            if (cleanNulling = accessDatas.size() > cleanNullSize) {
                log.debug("cleanNulling...");
                Set < String > keys = accessDatas.keySet();
                for (String key: keys) {
                    List < Long > points = accessDatas.get(key);
                    if (points.isEmpty()) {
                        points = null;
                        accessDatas.remove(key);
                    }
                }
                cleanNulling = false;
            }

            idsIterator = accessDatas.keySet().iterator();
            gloabalScanFlag = 0;
        } else {
            idsIterator = maybeFullIds.iterator();
            gloabalScanFlag++;
        }

        while (idsIterator.hasNext()) {
            accessPoints = accessDatas.get(idsIterator.next());
            //
            removeExpirePoints(accessPoints, currentTime);
        }
    }

},
1000, 1000, TimeUnit.MILLISECONDS);

移除过期的请求时间戳记录

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
private int removeExpirePoints(List<Long> ponits,long currentTimeMillis){
        int removeNums = 0;
        if(ponits == null || ponits.isEmpty()){
            return removeNums;
        }
        Iterator<Long> pointsIterator = ponits.iterator();  
        while (pointsIterator.hasNext()) {
            if(pointsIterator.next().compareTo(currentTimeMillis - timeWindowMillis) <= 0){
                pointsIterator.remove();
                removeNums++;
            }else{
                break;
            }
        }  

   return removeNums;
}

频控检查

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
/**
 * 访问频率检查
 * @param identification 用户标识(ip or sessionId)
 * @param uri
 * @return
 * @copyright http://www.jeesuite.com
*/
private boolean requestFrequencyCheck(String identification, String uri) {

    while (cleanNulling);

    boolean result = false;
    long currentTime = System.currentTimeMillis();
    List < Long > accessPoints = accessDatas.get(identification);
    try {
        if (accessPoints == null) {
            accessPoints = new Vector < >(permits);
            accessDatas.put(identification, accessPoints);
        }

        int size;
        if ((size = accessPoints.size()) < permits) {
            if (size >= putFullQueueSize) {
                maybeFullIds.add(identification);
            }
            result = true;
        } else {
            int removeNums = removeExpirePoints(accessPoints, currentTime);
            result = removeNums > 0;
        }
        return result;
    } finally {
        accessPoints.add(currentTime);
    }
}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2017-11-19,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
shiro权限控制(二):分布式架构中shiro的实现
前言: 前段时间在搭建公司游戏框架安全验证的时候,就想到之前web最火的shiro框架,虽然后面实践发现在netty中不太适用,最后自己模仿shiro写了一个缩减版的,但是中间花费两天时间弄出来的shiro可不能白费,这里给大家出个简单的教程说明吧。 shiro的基本介绍这里就不再说了,可以自行翻阅博主之前写的shiro教程,这篇文章主要说明分布式架构下shiro的session共享问题。 一、原理描述 无论分布式、还是集群下,项目都需要获取登录用户的信息,而不可能做的就是让客户在每个系统或者每个模块中反复
生活创客
2018/03/29
1.8K0
Spring Boot基于JWT的用户实时在线数获取方法
本文不详细叙述什么是JWT(Json web token),谷歌百度上关于这个的文章很多了,这里主要讲具体的代码实现。 OnlineCounter.java @Component public class OnlineCounter { //每次打开此类只初始化一次countMap private static Map countMap = new ConcurrentHashMap<String,Object>(); public void insertToken(String
水煮麥楽雞
2022/11/20
9870
Java集合类操作优化经验总结
本文首先针对 Java 集合接口进行了一些介绍,并对这些接口的实现类进行详细描述,包括 LinkedList、ArrayList、Vector、Stack、Hashtable、HashMap、WeakHashMap 等,然后对一些实现类的实现方式和使用经验进行讲解,同时重点介绍 WeakHashMap。希望通过本文介绍,可以让读者对集合的操作方式、注意事项等有一些了解。 在实际的项目开发中会有很多的对象,如何高效、方便地管理对象,成为影响程序性能与可维护性的重要环节。Java 提供了集合框架来解决此类问题,
用户1667431
2018/04/18
1.3K0
Java高频面试之集合篇
minCapacity=size+要添加元素的个数(add(E e)与addAll(Collection<? extends E> c))
九转成圣
2024/04/10
740
Java高频面试之集合篇
Ribbon的BestAvailableRule和RetryRule
                                                                              图1
克虏伯
2019/10/05
2.6K1
封装httpClient工具类进行get、post、put、delete的http接口请求,可添加请求头与参数,支持多线程
发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/157763.html原文链接:https://javaforall.cn
全栈程序员站长
2022/09/18
2.6K0
Spring Boot中基于AOP和Semaphore实现API限流
调用速率限制是 Web API 中的常见要求,旨在防止滥用并确保公平使用资源。借助Spring Boot 中的 AOP,我们可以通过拦截方法调用并限制在特定时间范围内允许的请求数量来实现速率限制。
公众号:码到三十五
2024/10/19
1540
JAVA学习笔记(三)
@SuppressWarnings("resource")是用来压制资源泄露警告的。比如使用io类,最后没有关闭。 Set集合特点: 1)无序,不随机 2)元素唯一 3)没下标 注意:Collection List Set 是接口 注意:因为Set 没有下标,所以取值是不能用for,只能用迭代器 HashSet: 内部结构是哈希表,所以元素唯一,无序,没下标。 TreeSet: 内部是二叉树,元素可以进行比较,可以按自然顺序比较,也可以由程序员自定义比较方式,没下 标。 LinkedHashSet:内部结构是哈希表及链表组成,所以有序,元素唯一,没下标。 HashSet: HashSet<String> ss = new HashSet<String>(); ss.add("a"); ss.add("k"); ss.add("d"); ss.add("k");
HUC思梦
2020/09/03
3730
Java 中九种 Map 的遍历方式,你一般用的是哪种呢?
日常工作中 Map 绝对是我们 Java 程序员高频使用的一种数据结构,那 Map 都有哪些遍历方式呢?这篇文章阿粉就带大家看一下,看看你经常使用的是哪一种。
Java极客技术
2022/12/04
7280
Java 中九种 Map 的遍历方式,你一般用的是哪种呢?
Java 集合(5)-- Collections源码刨到底式详解
一、Collections接口是做什么的? 用官网文档的介绍: The polymorphic algorithms described here are pieces of reusable functionality provided by the Java platform. All of them come from the Collections class, and all take the form of static methods whose first argument is the c
秦怀杂货店
2020/11/19
3840
Java 集合(5)-- Collections源码刨到底式详解
我用Java几分钟处理完30亿个数据...
点击上方蓝色字体,选择“设为星标” 回复”学习资料“获取学习宝典 文章来源:https://c1n.cn/GM8hb 目录 场景说明 模拟数据 场景分析 读取数据 处理数据 遇到的问题 场景说明 现有一个 10G 文件的数据,里面包含了 18-70 之间的整数,分别表示 18-70 岁的人群数量统计,假设年龄范围分布均匀,分别表示系统中所有用户的年龄数,找出重复次数最多的那个数,现有一台内存为 4G、2 核 CPU 的电脑,请写一个算法实现。         23,31,42,19,60,30,36,
猿天地
2022/05/16
5000
我用Java几分钟处理完30亿个数据...
LinkedList源码解析
LinkedList是一个实现了List接口和Deque接口的双端链表。LinkedList底层的链表结构使它支持高效的插入和删除操作,另外它实现了Deque接口,使得LinkedList类也具有队列的特性; LinkedList不是线程安全的,如果想使LinkedList变成线程安全的,可以调用静态类Collections类中的synchronizedList方法:
黑洞代码
2021/01/28
9310
LinkedList源码解析
Java求两集合中元素交集的四种方法对比总结
最近在做项目的时候有用到对两个集合中的元素进行对比求其交集的情况,因为涉及到的数据量比较大,所以在进行求两个集合中元素交集的时候,就应该考虑到程序运行的时间消耗等问题,
灰小猿
2022/05/05
1.1K0
基于Servlet3.0异步特性实现请求鉴权与转发
项目背景 在多个内网系统之上,增加一个网关服务,统一对第三方应用进行鉴权与认证,方可对内部资源服务进行访问,网关服务主要起到鉴权认证,请求转发主要借助Servlet3.0的异步特性实现,结合springboot进行开发。 将请求异步化的好处 同步请求会将整个请求链路的发起,解析,响应在一个同步逻辑中进行。 采用异步处化可以将请求中耗时操作交给线程池做异步处理,在高并发场景下,通过调用一个非web服务线程处理耗时逻辑,提高系统并发性。 由于线程池是隔离的,可以对线程池做业务隔离分组,进行请求分级,监控等。 思
春哥大魔王
2018/04/17
1.3K0
35 个 Java 代码性能优化总结
本文主要讲解了Java开发中的一些常见陷阱和最佳实践,包括命名约定、代码格式化、异常处理、集合操作、线程同步、资源关闭等。通过这些实践,可以提高Java开发的质量和效率,同时也有利于团队协作和代码维护。
Java后端工程师
2017/12/07
4.2K0
Java知识梳理 | 详析三大集合类(附实用例程 + 实践练习题)
1.3. 常用的集合有List集合、Set集合和Map集合;   List与Set继承了Collection接口,各接口还提供了不同的实现类。 常用集合类的继承关系如下:
凌川江雪
2019/01/28
1.3K0
map遍历方式及效率_java遍历map集合
其实foreach的语法只是对iterator进行了简单的包装,使用起来更加方便而已,但是如果在foreach循环体内,对集合元素进行删除添加操作的时候,会报出ConcurrentModificationException,并发修改异常。如果需要在遍历集合的时候对象集合中元素进行删除操作,需要使用iterator的遍历方式,iterator自带的remove删除方式不会报出异常。
全栈程序员站长
2022/11/08
1.4K0
Java遍历Map效率对比
Java 中Map容器的遍历有多种方式,但是不同的方式效率会大有不同,以前没有注意这些细节,随意使用遍历方式在本地可能没有什么影响,但是在项目在高频使用需要特别注意,尽量使用高效的方式。
全栈程序员站长
2022/07/23
9470
​什么是限流,如何限流
某天小明突然发现自己的接口请求突然之间涨到了原来的10倍,接口几乎不能使用,产生了一系列连锁反应,导致了整个系统崩溃。这就好比,老电闸中都安装了保险丝,一旦使用大功率设备,保险丝就会熔断,保证各个电器不被强电流烧坏,系统也同样安装保险丝,防止非预期请求过大,引起系统瘫痪。
王小明_HIT
2021/05/20
3.3K0
Java中的容器
在Java中有常用的三种类型的容器,分别是List 、Map、Set,基于这个三个基本的类型,派生出很多其它的类型,具体关系如下:
付威
2018/12/05
1.8K0
Java中的容器
相关推荐
shiro权限控制(二):分布式架构中shiro的实现
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验