|
@@ -40,22 +40,23 @@ public class RateLimitFilter extends OncePerRequestFilter {
|
|
|
currentDate = today;
|
|
currentDate = today;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- // 每 IP 每分钟限制(事前检查,防刷)
|
|
|
|
|
String ip = request.getRemoteAddr();
|
|
String ip = request.getRemoteAddr();
|
|
|
- var ipCount = minuteCounter.computeIfAbsent(ip, k -> new AtomicInteger(0));
|
|
|
|
|
- if (ipCount.incrementAndGet() > props.getPerMinute()) {
|
|
|
|
|
- response.setStatus(429);
|
|
|
|
|
- response.setContentType("application/json;charset=UTF-8");
|
|
|
|
|
- response.getWriter().write("{\"error\":\"请求过于频繁,请稍后再试\",\"code\":429}");
|
|
|
|
|
- return;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- // 每日限制:先检查是否已超,超了直接拒(不浪费 DashScope API)
|
|
|
|
|
boolean isChatApi = request.getRequestURI().contains("/chat/")
|
|
boolean isChatApi = request.getRequestURI().contains("/chat/")
|
|
|
&& request.getMethod().equalsIgnoreCase("POST");
|
|
&& request.getMethod().equalsIgnoreCase("POST");
|
|
|
- String userId = null;
|
|
|
|
|
|
|
+
|
|
|
|
|
+ // 仅 chat 接口走限流,药品库等接口跳过
|
|
|
if (isChatApi) {
|
|
if (isChatApi) {
|
|
|
- userId = getUserId(request);
|
|
|
|
|
|
|
+ // 每 IP 每分钟限制
|
|
|
|
|
+ var ipCount = minuteCounter.computeIfAbsent(ip, k -> new AtomicInteger(0));
|
|
|
|
|
+ if (ipCount.incrementAndGet() > props.getPerMinute()) {
|
|
|
|
|
+ response.setStatus(429);
|
|
|
|
|
+ response.setContentType("application/json;charset=UTF-8");
|
|
|
|
|
+ response.getWriter().write("{\"error\":\"请求过于频繁,请稍后再试\",\"code\":429}");
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 每日限制
|
|
|
|
|
+ String userId = getUserId(request);
|
|
|
if (userId == null) userId = "ip:" + ip;
|
|
if (userId == null) userId = "ip:" + ip;
|
|
|
var dailyCount = dailyCounter.computeIfAbsent(userId, k -> new AtomicInteger(0));
|
|
var dailyCount = dailyCounter.computeIfAbsent(userId, k -> new AtomicInteger(0));
|
|
|
if (dailyCount.get() >= props.getPerDay()) {
|
|
if (dailyCount.get() >= props.getPerDay()) {
|
|
@@ -76,7 +77,9 @@ public class RateLimitFilter extends OncePerRequestFilter {
|
|
|
filterChain.doFilter(request, statusWrapper);
|
|
filterChain.doFilter(request, statusWrapper);
|
|
|
|
|
|
|
|
// 只有成功响应(2xx)才计入每日次数
|
|
// 只有成功响应(2xx)才计入每日次数
|
|
|
- if (isChatApi && userId != null) {
|
|
|
|
|
|
|
+ if (isChatApi) {
|
|
|
|
|
+ String userId = getUserId(request);
|
|
|
|
|
+ if (userId == null) userId = "ip:" + ip;
|
|
|
int status = statusWrapper.getStatus();
|
|
int status = statusWrapper.getStatus();
|
|
|
if (status >= 200 && status < 300) {
|
|
if (status >= 200 && status < 300) {
|
|
|
dailyCounter.computeIfAbsent(userId, k -> new AtomicInteger(0)).incrementAndGet();
|
|
dailyCounter.computeIfAbsent(userId, k -> new AtomicInteger(0)).incrementAndGet();
|
|
@@ -96,4 +99,4 @@ public class RateLimitFilter extends OncePerRequestFilter {
|
|
|
}
|
|
}
|
|
|
return null;
|
|
return null;
|
|
|
}
|
|
}
|
|
|
-}
|
|
|
|
|
|
|
+}
|