多维度访问次数限制策略

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

相关文章

在JS中的设计模式的单例模式、策略模式、代理模式、原型模式浅讲

1. 单例模式(Singleton Pattern) 确保一个类只有一个实例,并提供一个全局访问点。 示例代码: class Singleton {constructor() {if (Singleton.instance) {return Singleton.instance;}Singleton.instance = this;this.data = [];}addData(value)

安卓链接正常显示,ios#符被转义%23导致链接访问404

原因分析: url中含有特殊字符 中文未编码 都有可能导致URL转换失败,所以需要对url编码处理  如下: guard let allowUrl = webUrl.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) else {return} 后面发现当url中有#号时,会被误伤转义为%23,导致链接无法访问

poj 2135 有流量限制的最小费用最大流

题意: 农场里有n块地,其中约翰的家在1号地,二n号地有个很大的仓库。 农场有M条道路(双向),道路i连接着ai号地和bi号地,长度为ci。 约翰希望按照从家里出发,经过若干块地后到达仓库,然后再返回家中的顺序带朋友参观。 如果要求往返不能经过同一条路两次,求参观路线总长度的最小值。 解析: 如果只考虑去或者回的情况,问题只不过是无向图中两点之间的最短路问题。 但是现在要去要回

poj 3422 有流量限制的最小费用流 反用求最大 + 拆点

题意: 给一个n*n(50 * 50) 的数字迷宫,从左上点开始走,走到右下点。 每次只能往右移一格,或者往下移一格。 每个格子,第一次到达时可以获得格子对应的数字作为奖励,再次到达则没有奖励。 问走k次这个迷宫,最大能获得多少奖励。 解析: 拆点,拿样例来说明: 3 2 1 2 3 0 2 1 1 4 2 3*3的数字迷宫,走两次最大能获得多少奖励。 将每个点拆成两个

poj 2195 bfs+有流量限制的最小费用流

题意: 给一张n * m(100 * 100)的图,图中” . " 代表空地, “ M ” 代表人, “ H ” 代表家。 现在,要你安排每个人从他所在的地方移动到家里,每移动一格的消耗是1,求最小的消耗。 人可以移动到家的那一格但是不进去。 解析: 先用bfs搞出每个M与每个H的距离。 然后就是网络流的建图过程了,先抽象出源点s和汇点t。 令源点与每个人相连,容量为1,费用为

poj 3068 有流量限制的最小费用网络流

题意: m条有向边连接了n个仓库,每条边都有一定费用。 将两种危险品从0运到n-1,除了起点和终点外,危险品不能放在一起,也不能走相同的路径。 求最小的费用是多少。 解析: 抽象出一个源点s一个汇点t,源点与0相连,费用为0,容量为2。 汇点与n - 1相连,费用为0,容量为2。 每条边之间也相连,费用为每条边的费用,容量为1。 建图完毕之后,求一条流量为2的最小费用流就行了

hdu 3065 AC自动机 匹配串编号以及出现次数

题意: 仍旧是天朝语题。 Input 第一行,一个整数N(1<=N<=1000),表示病毒特征码的个数。 接下来N行,每行表示一个病毒特征码,特征码字符串长度在1—50之间,并且只包含“英文大写字符”。任意两个病毒特征码,不会完全相同。 在这之后一行,表示“万恶之源”网站源码,源码字符串长度在2000000之内。字符串中字符都是ASCII码可见字符(不包括回车)。

两个月冲刺软考——访问位与修改位的题型(淘汰哪一页);内聚的类型;关于码制的知识点;地址映射的相关内容

1.访问位与修改位的题型(淘汰哪一页) 访问位:为1时表示在内存期间被访问过,为0时表示未被访问;修改位:为1时表示该页面自从被装入内存后被修改过,为0时表示未修改过。 置换页面时,最先置换访问位和修改位为00的,其次是01(没被访问但被修改过)的,之后是10(被访问了但没被修改过),最后是11。 2.内聚的类型 功能内聚:完成一个单一功能,各个部分协同工作,缺一不可。 顺序内聚:

缓存策略使用总结

缓存是提高系统性能的最简单方法之一。相对而言,数据库(or NoSQL数据库)的速度比较慢,而速度却又是致胜的关键。 如果使用得当,缓存可以减少相应时间、减少数据库负载以及节省成本。本文罗列了几种缓存策略,选择正确的一种会有很大的不同。缓存策略取决于数据和数据访问模式。换句话说,数据是如何写和读的。例如: 系统是写多读少的吗?(例如基于时间的日志)数据是否是只写入一次并被读取多次?(例如用户配

Flink任务重启策略

概述 Flink支持不同的重启策略,以在故障发生时控制作业如何重启集群在启动时会伴随一个默认的重启策略,在没有定义具体重启策略时会使用该默认策略。如果在工作提交时指定了一个重启策略,该策略会覆盖集群的默认策略默认的重启策略可以通过 Flink 的配置文件 flink-conf.yaml 指定。配置参数 restart-strategy 定义了哪个策略被使用。常用的重启策略: 固定间隔 (Fixe