50 lines
1.5 KiB
Java
50 lines
1.5 KiB
Java
package com.imyeyu.api.annotation;
|
|
|
|
import jakarta.servlet.http.HttpServletRequest;
|
|
import jakarta.servlet.http.HttpServletResponse;
|
|
import lombok.extern.slf4j.Slf4j;
|
|
import com.imyeyu.java.bean.timi.TimiCode;
|
|
import com.imyeyu.java.bean.timi.TimiException;
|
|
import com.imyeyu.spring.TimiSpring;
|
|
import com.imyeyu.spring.annotation.RequestRateLimitAbstractInterceptor;
|
|
import com.imyeyu.spring.util.Redis;
|
|
import com.imyeyu.utils.Time;
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
import org.springframework.beans.factory.annotation.Qualifier;
|
|
import org.springframework.stereotype.Component;
|
|
|
|
/**
|
|
* 请求频率限制处理器
|
|
*
|
|
* @author 夜雨
|
|
* @since 2021-08-16 18:07
|
|
*/
|
|
@Slf4j
|
|
@Component
|
|
public class RequestRateLimitInterceptor extends RequestRateLimitAbstractInterceptor {
|
|
|
|
@Autowired
|
|
@Qualifier("redisRateLimit")
|
|
private Redis<String, Integer> redisRequestRateLimit;
|
|
|
|
@Override
|
|
public boolean beforeRun(HttpServletRequest req, HttpServletResponse resp, String id, int cycle, int limit) {
|
|
// 键
|
|
String key = "TimiServerAPI." + TimiSpring.getRequestIP() + "." + id;
|
|
if (redisRequestRateLimit.has(key)) {
|
|
Integer count = redisRequestRateLimit.get(key);
|
|
if (count != null) {
|
|
if (count < limit) {
|
|
redisRequestRateLimit.setAndKeepTTL(key, ++count);
|
|
} else {
|
|
log.warn("请求频率过高:[" + key + "].C" + count + "L" + limit);
|
|
throw new TimiException(TimiCode.REQUEST_BAD).msgKey("request_rate_limit");
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
redisRequestRateLimit.set(key, 0, Time.S * cycle);
|
|
return true;
|
|
}
|
|
}
|