Files
TimiServerAPI/src/main/java/com/imyeyu/api/annotation/RequestRateLimitInterceptor.java
2025-07-22 15:26:14 +08:00

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;
}
}