Files
TimiServerAPI/src/main/java/com/imyeyu/api/annotation/RequestRateLimitInterceptor.java
T
Timi 15bf9bd688
CI / build-deploy (pull_request) Failing after 2m52s
CI / notify-on-failure (pull_request) Successful in 0s
v1.0.3
2026-08-01 01:13:08 +08:00

56 lines
1.6 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 {
private static final String KEY_PREFIX = "REQUEST:RATE_LIMIT:";
@Autowired
@Qualifier("redisRateLimit")
private Redis<String, Integer> redis;
@Override
public boolean beforeRun(HttpServletRequest req, HttpServletResponse resp, String id, int cycle, int limit) {
// 键
String key = getKey(id);
if (redis.has(key)) {
Integer count = redis.get(key);
if (count != null) {
if (count < limit) {
redis.setAndKeepTTL(key, ++count);
} else {
log.warn("请求频率过高:[" + key + "].C" + count + "L" + limit);
throw new TimiException(TimiCode.REQUEST_BAD, "request_rate_limit");
}
}
return true;
}
redis.set(key, 0, Time.S * cycle);
return true;
}
private String getKey(String id) {
return "%sTIMISERVERAPI:%s:%s".formatted(KEY_PREFIX, TimiSpring.getRequestIP(), id);
}
}