多维度访问次数限制策略

2024-01-14 13:58

本文主要是介绍多维度访问次数限制策略,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

类型维度
梯度维度
时间段维度

配置文件:

[{"seconds": 10,"times": 5,"type": "user_method","errMsg": ""},{"seconds": 30,"times": 15,"type": "user_method","errMsg": ""},{"times": 100,"type": "user","errMsg": ""},{"times": 200,"type": "method","errMsg": ""},{"times": 200,"type": "range_time","range_time": "18:00-19:00","errMsg": ""},{"times": 200,"type": "range_time","range_time": "19:00-20:00","errMsg": ""}
]

实现代码:

public RequestLimit tryRequest(final List<RequestLimit> requestLimitList, final String methodName, final Integer userId) {Assert.isTrue(StringUtil.isNotBlank(methodName), "tryRequest param methodName is empty!");Assert.isTrue(userId != null && userId > 0, "tryRequest param userId is empty!");Object ret = runTask(new Callback() {@Overridepublic RequestLimit onTask(Jedis jedis) {boolean flag = true;log.info(String.format("[reqLimit_request] \t methodName, userId\t : %s,%s", methodName, userId));for (RequestLimit limit : requestLimitList) {Integer seconds = limit.getSeconds();Integer times = limit.getTimes();String type = limit.getType() ;if (flag && "user_method".equals(type)) {flag = limitUserMethod(jedis, seconds, times, methodName, userId);} else if (flag && "user".equals(type)) {flag = limitUser(jedis, times, userId);} else if (flag && "method".equals(type)) {flag = limitMethod(jedis, times, methodName);} else if (flag && "range".equals(type)) {flag = limitRangeTime(jedis, limit, userId);}if (!flag) {return limit;}}log.info(String.format("[reqLimit_pass] \t seconds, methodName, userId :\t %s,%s", methodName, userId));return null;}});return ret == null ? null : (RequestLimit) ret;
}private boolean limitRangeTime(Jedis jedis, RequestLimit limit, Integer userId) {long nowTime = System.currentTimeMillis();long rangeStartTime = limit.getRangeStartTime();long rangeEndTime = limit.getRangeEndTime();Integer times = limit.getTimes();PreconditionsUtil.checkArguments(times != null, "400", "RequestLimit times is null");if (rangeStartTime <= nowTime && nowTime < rangeEndTime) {long seconds = rangeEndTime - nowTime;log.info(String.format("[reqLimit_error:USER_RANGE_TIME] \t range_time, times, seconds, userId :\t %s,%s,%s,%s",limit.getRangeTime(), times, seconds, userId));final String key = String.format(USER_RANGE_TIME_REQUEST_LIMIT, rangeEndTime, userId);String mistr = jedis.get(key);if (mistr == null || Integer.parseInt(mistr) == 0) {jedis.incr(key);jedis.expire(key, (int) seconds);} else if (jedis.incr(key) >= times) {log.error(String.format("[reqLimit_error:USER_RANGE_TIME] \t times, seconds, userId :\t %s,%s,%s",jedis.get(key), seconds, userId));return false;}}return true;
}private boolean limitUser(Jedis jedis, Integer times, Integer userId) {long dayEndTime = DateUtil.getDayEndTime();final String key = String.format(USER_REQUEST_LIMIT, dayEndTime, userId);long seconds = dayEndTime - System.currentTimeMillis();String mistr = jedis.get(key);log.info(String.format("[reqLimit_error:USER] \t times, seconds, userId :\t %s,%s,%s",times, seconds, userId));if (mistr == null || Integer.parseInt(mistr) == 0) {jedis.incr(key);jedis.expire(key, (int) seconds);} else if (jedis.incr(key) >= times) {log.error(String.format("[reqLimit_error:USER] \t times, seconds, userId :\t %s,%s,%s",jedis.get(key), seconds, userId));return false;}return true;
}private boolean limitMethod(Jedis jedis, Integer times, String methodName) {long dayEndTime = DateUtil.getDayEndTime();final String key = String.format(METHOD_REQUEST_LIMIT, dayEndTime, methodName);long seconds = dayEndTime - System.currentTimeMillis();log.info(String.format("[reqLimit_error:METHOD] \t times, seconds, methodName :\t %s,%s,%s",times, seconds, methodName));String mistr = jedis.get(key);if (mistr == null || Integer.parseInt(mistr) == 0) {jedis.incr(key);jedis.expire(key, (int) seconds);} else if (jedis.incr(key) >= times) {log.error(String.format("[RequireRequestLimit_over:METHOD] \t times, seconds, methodName :\t",jedis.get(key), seconds, methodName));return false;}return true;
}private boolean limitUserMethod(Jedis jedis, Integer seconds, Integer times, String methodName, Integer userId) {final String key = String.format(METHOD_USER_REQUEST_LIMIT, seconds, methodName, userId);String mistr = jedis.get(key);log.info(String.format("[reqLimit_error:METHOD] \t times, seconds, methodName, userId :\t %s,%s,%s,%s",times, seconds, methodName, userId));if (mistr == null || Integer.parseInt(mistr) == 0) {jedis.incr(key);jedis.expire(key, seconds);} else if (jedis.incr(key) >= times) {log.error(String.format("[RequireRequestLimit_over:USER_METHOD] \t times, seconds, methodName, userId :\t",jedis.get(key), seconds, methodName, userId));return false;}return true;
}

这篇关于多维度访问次数限制策略的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/605408

相关文章

Redis多种内存淘汰策略及配置技巧分享

《Redis多种内存淘汰策略及配置技巧分享》本文介绍了Redis内存满时的淘汰机制,包括内存淘汰机制的概念,Redis提供的8种淘汰策略(如noeviction、volatile-lru等)及其适用场... 目录前言一、什么是 Redis 的内存淘汰机制?二、Redis 内存淘汰策略1. pythonnoe

Java访问修饰符public、private、protected及默认访问权限详解

《Java访问修饰符public、private、protected及默认访问权限详解》:本文主要介绍Java访问修饰符public、private、protected及默认访问权限的相关资料,每... 目录前言1. public 访问修饰符特点:示例:适用场景:2. private 访问修饰符特点:示例:

Python 中 requests 与 aiohttp 在实际项目中的选择策略详解

《Python中requests与aiohttp在实际项目中的选择策略详解》本文主要介绍了Python爬虫开发中常用的两个库requests和aiohttp的使用方法及其区别,通过实际项目案... 目录一、requests 库二、aiohttp 库三、requests 和 aiohttp 的比较四、requ

Python 标准库time时间的访问和转换问题小结

《Python标准库time时间的访问和转换问题小结》time模块为Python提供了处理时间和日期的多种功能,适用于多种与时间相关的场景,包括获取当前时间、格式化时间、暂停程序执行、计算程序运行时... 目录模块介绍使用场景主要类主要函数 - time()- sleep()- localtime()- g

Redis过期键删除策略解读

《Redis过期键删除策略解读》Redis通过惰性删除策略和定期删除策略来管理过期键,惰性删除策略在键被访问时检查是否过期并删除,节省CPU开销但可能导致过期键滞留,定期删除策略定期扫描并删除过期键,... 目录1.Redis使用两种不同的策略来删除过期键,分别是惰性删除策略和定期删除策略1.1惰性删除策略

使用Python实现批量访问URL并解析XML响应功能

《使用Python实现批量访问URL并解析XML响应功能》在现代Web开发和数据抓取中,批量访问URL并解析响应内容是一个常见的需求,本文将详细介绍如何使用Python实现批量访问URL并解析XML响... 目录引言1. 背景与需求2. 工具方法实现2.1 单URL访问与解析代码实现代码说明2.2 示例调用

关于Java内存访问重排序的研究

《关于Java内存访问重排序的研究》文章主要介绍了重排序现象及其在多线程编程中的影响,包括内存可见性问题和Java内存模型中对重排序的规则... 目录什么是重排序重排序图解重排序实验as-if-serial语义内存访问重排序与内存可见性内存访问重排序与Java内存模型重排序示意表内存屏障内存屏障示意表Int

SpringBoot实现基于URL和IP的访问频率限制

《SpringBoot实现基于URL和IP的访问频率限制》在现代Web应用中,接口被恶意刷新或暴力请求是一种常见的攻击手段,为了保护系统资源,需要对接口的访问频率进行限制,下面我们就来看看如何使用... 目录1. 引言2. 项目依赖3. 配置 Redis4. 创建拦截器5. 注册拦截器6. 创建控制器8.

SpringBoot如何访问jsp页面

《SpringBoot如何访问jsp页面》本文介绍了如何在SpringBoot项目中进行Web开发,包括创建项目、配置文件、添加依赖、控制层修改、测试效果以及在IDEA中进行配置的详细步骤... 目录SpringBoot如何访问JSP页python面简介实现步骤1. 首先创建的项目一定要是web项目2. 在

Linux限制ip访问的解决方案

《Linux限制ip访问的解决方案》为了修复安全扫描中发现的漏洞,我们需要对某些服务设置访问限制,具体来说,就是要确保只有指定的内部IP地址能够访问这些服务,所以本文给大家介绍了Linux限制ip访问... 目录背景:解决方案:使用Firewalld防火墙规则验证方法深度了解防火墙逻辑应用场景与扩展背景: