多维度访问次数限制策略

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

相关文章

浅谈mysql的sql_mode可能会限制你的查询

《浅谈mysql的sql_mode可能会限制你的查询》本文主要介绍了浅谈mysql的sql_mode可能会限制你的查询,这个问题主要说明的是,我们写的sql查询语句违背了聚合函数groupby的规则... 目录场景:问题描述原因分析:解决方案:第一种:修改后,只有当前生效,若是mysql服务重启,就会失效;

SpringBoot如何通过Map实现策略模式

《SpringBoot如何通过Map实现策略模式》策略模式是一种行为设计模式,它允许在运行时选择算法的行为,在Spring框架中,我们可以利用@Resource注解和Map集合来优雅地实现策略模式,这... 目录前言底层机制解析Spring的集合类型自动装配@Resource注解的行为实现原理使用直接使用M

使用Dify访问mysql数据库详细代码示例

《使用Dify访问mysql数据库详细代码示例》:本文主要介绍使用Dify访问mysql数据库的相关资料,并详细讲解了如何在本地搭建数据库访问服务,使用ngrok暴露到公网,并创建知识库、数据库访... 1、在本地搭建数据库访问的服务,并使用ngrok暴露到公网。#sql_tools.pyfrom

Javascript访问Promise对象返回值的操作方法

《Javascript访问Promise对象返回值的操作方法》这篇文章介绍了如何在JavaScript中使用Promise对象来处理异步操作,通过使用fetch()方法和Promise对象,我们可以从... 目录在Javascript中,什么是Promise1- then() 链式操作2- 在之后的代码中使

Redis 内存淘汰策略深度解析(最新推荐)

《Redis内存淘汰策略深度解析(最新推荐)》本文详细探讨了Redis的内存淘汰策略、实现原理、适用场景及最佳实践,介绍了八种内存淘汰策略,包括noeviction、LRU、LFU、TTL、Rand... 目录一、 内存淘汰策略概述二、内存淘汰策略详解2.1 ​noeviction(不淘汰)​2.2 ​LR

如何使用Docker部署FTP和Nginx并通过HTTP访问FTP里的文件

《如何使用Docker部署FTP和Nginx并通过HTTP访问FTP里的文件》本文介绍了如何使用Docker部署FTP服务器和Nginx,并通过HTTP访问FTP中的文件,通过将FTP数据目录挂载到N... 目录docker部署FTP和Nginx并通过HTTP访问FTP里的文件1. 部署 FTP 服务器 (

Deepseek使用指南与提问优化策略方式

《Deepseek使用指南与提问优化策略方式》本文介绍了DeepSeek语义搜索引擎的核心功能、集成方法及优化提问策略,通过自然语言处理和机器学习提供精准搜索结果,适用于智能客服、知识库检索等领域... 目录序言1. DeepSeek 概述2. DeepSeek 的集成与使用2.1 DeepSeek API

Redis的数据过期策略和数据淘汰策略

《Redis的数据过期策略和数据淘汰策略》本文主要介绍了Redis的数据过期策略和数据淘汰策略,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一... 目录一、数据过期策略1、惰性删除2、定期删除二、数据淘汰策略1、数据淘汰策略概念2、8种数据淘汰策略

本地搭建DeepSeek-R1、WebUI的完整过程及访问

《本地搭建DeepSeek-R1、WebUI的完整过程及访问》:本文主要介绍本地搭建DeepSeek-R1、WebUI的完整过程及访问的相关资料,DeepSeek-R1是一个开源的人工智能平台,主... 目录背景       搭建准备基础概念搭建过程访问对话测试总结背景       最近几年,人工智能技术

SpringBoot中的404错误:原因、影响及解决策略

《SpringBoot中的404错误:原因、影响及解决策略》本文详细介绍了SpringBoot中404错误的出现原因、影响以及处理策略,404错误常见于URL路径错误、控制器配置问题、静态资源配置错误... 目录Spring Boot中的404错误:原因、影响及处理策略404错误的出现原因1. URL路径错