类型维度
梯度维度
时间段维度
配置文件:
[
{
"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() {
@Override
public 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;
}