本文主要是介绍多维度访问次数限制策略,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
类型维度
梯度维度
时间段维度
配置文件:
[{"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;
}
这篇关于多维度访问次数限制策略的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!