一、设计思路(IP + 时间窗限流)
目标:
按 IP 维度
在 固定时间窗口(如 1 秒 / 1 分钟)
限制最大请求次数(如 100 次/分钟)
实现方式:
key = IP
value = 该 IP 在当前时间窗内的请求次数
时间窗过期自动清零
二、核心实现(Thread-safe + 本地缓存版)
方案:ConcurrentHashMap + AtomicInteger + 时间窗口
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;
public class IpRateLimiter {
// 每个 IP 的访问记录
private static class Counter {
AtomicInteger count = new AtomicInteger(0);
long windowStart;
}
private final ConcurrentHashMap<String, Counter> cache = new ConcurrentHashMap<>();
// 时间窗口(毫秒)
private final long windowSizeInMs;
// 每个窗口最大请求数
private final int maxRequest;
public IpRateLimiter(long windowSizeInMs, int maxRequest) {
this.windowSizeInMs = windowSizeInMs;
this.maxRequest = maxRequest;
// 定时清理过期数据(防止内存泄漏)
Executors.newSingleThreadScheduledExecutor()
.scheduleAtFixedRate(this::cleanup, windowSizeInMs, windowSizeInMs, TimeUnit.MILLISECONDS);
}
public boolean allowRequest(String ip) {
long now = System.currentTimeMillis();
Counter counter = cache.computeIfAbsent(ip, k -> {
Counter c = new Counter();
c.windowStart = now;
return c;
});
synchronized (counter) {
// 如果已经进入新的时间窗口,重置
if (now - counter.windowStart > windowSizeInMs) {
counter.windowStart = now;
counter.count.set(0);
}
// 判断是否超过限制
if (counter.count.incrementAndGet() > maxRequest) {
return false;
}
return true;
}
}
private void cleanup() {
long now = System.currentTimeMillis();
for (String ip : cache.keySet()) {
Counter c = cache.get(ip);
if (c != null && now - c.windowStart > windowSizeInMs) {
cache.remove(ip);
}
}
}
}
三、Spring Boot 使用方式(Interceptor)
1. 定义拦截器
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.HandlerInterceptor;
public class RateLimitInterceptor implements HandlerInterceptor {
private final IpRateLimiter rateLimiter;
public RateLimitInterceptor(IpRateLimiter rateLimiter) {
this.rateLimiter = rateLimiter;
}
@Override
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response,
Object handler) throws Exception {
String ip = getClientIp(request);
if (!rateLimiter.allowRequest(ip)) {
response.setStatus(429);
response.getWriter().write("Too Many Requests");
return false;
}
return true;
}
private String getClientIp(HttpServletRequest request) {
String ip = request.getHeader("X-Forwarded-For");
if (ip == null || ip.isEmpty()) {
ip = request.getRemoteAddr();
}
return ip.split(",")[0];
}
}
2. 注册拦截器
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.*;
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
IpRateLimiter limiter = new IpRateLimiter(60_000, 100); // 1分钟100次
registry.addInterceptor(new RateLimitInterceptor(limiter))
.addPathPatterns("/**");
}
}
https://vk.com/topic-238443049_60626270
https://vk.com/topic-238443049_60626540
https://vk.com/topic-238443049_60626785
https://vk.com/topic-238443049_60627004
https://vk.com/topic-238443049_60627233
https://vk.com/topic-238443049_60627494
https://vk.com/topic-238443049_60627707
https://vk.com/topic-238443049_60627985
https://vk.com/topic-238443049_60628226
https://vk.com/topic-238443049_60628474
https://vk.com/topic-238443049_60628693
https://vk.com/topic-238443049_60628922
https://vk.com/topic-238443049_60629182
https://vk.com/topic-238443049_60629432
https://vk.com/topic-238443049_60629658
https://vk.com/topic-238443049_60629904
https://vk.com/topic-238443049_60630187
https://vk.com/topic-238443049_60630428
https://vk.com/topic-238443049_60630756
https://vk.com/topic-238443049_60631123
https://vk.com/topic-238443049_60631525
https://vk.com/topic-238443049_60631966
https://vk.com/topic-238443049_60632434
https://vk.com/topic-238443049_60632885
https://vk.com/topic-238443049_60633356
https://vk.com/topic-238443049_60633799
https://vk.com/topic-238443049_60634289
https://vk.com/topic-238443049_60634790
https://vk.com/topic-238443049_60635242
https://vk.com/topic-238443049_60635763
https://vk.com/topic-238443049_60636372
https://vk.com/topic-238443049_60636883
https://vk.com/topic-238443049_60637312
https://vk.com/topic-238443049_60637842
https://vk.com/topic-238443049_60638330
https://vk.com/topic-238443049_60638731
https://vk.com/topic-238443049_60639172
https://vk.com/topic-238443049_60639546
https://vk.com/topic-238443049_60639907
https://vk.com/topic-238443049_60640251
https://vk.com/topic-238443049_60640639
https://vk.com/topic-238443049_60641029
https://vk.com/topic-238443049_60641468
https://vk.com/topic-238443049_60641959
https://vk.com/topic-238443049_60642478
https://vk.com/topic-238443049_60642901
https://vk.com/topic-238443049_60643403
https://vk.com/topic-238443049_60643942
https://vk.com/topic-238443049_60644345
https://vk.com/topic-238443049_60644751
https://vk.com/topic-238443049_60645092
https://vk.com/topic-238443049_60645454
https://vk.com/topic-238443049_60645786
https://vk.com/topic-238443049_60646145
https://vk.com/topic-238443049_60646504
https://vk.com/topic-238443049_60646896
https://vk.com/topic-238443049_60647255
https://vk.com/topic-238443049_60649686
https://vk.com/topic-238443049_60650278
https://vk.com/topic-238443049_60650880
https://vk.com/topic-238443049_60651432
https://vk.com/topic-238443049_60651974
https://vk.com/topic-238443049_60652437
https://vk.com/topic-238443049_60652831
https://vk.com/topic-238443049_60653268
https://vk.com/topic-238443049_60653722
https://vk.com/topic-238443049_60654183
https://vk.com/topic-238443049_60654612
https://vk.com/topic-238443049_60655110
https://vk.com/topic-238443049_60655605
https://vk.com/topic-238443049_60656114
https://vk.com/topic-238443049_60656597
https://vk.com/topic-238443049_60657122
https://vk.com/topic-238443049_60657665
https://vk.com/topic-238443049_60658251
https://vk.com/topic-238443049_60658922
https://vk.com/topic-238443049_60659784
https://vk.com/topic-238443049_60660738
https://vk.com/topic-238443049_60661619
https://vk.com/topic-238443049_60662506
https://vk.com/topic-238443049_60663373
https://vk.com/topic-238443049_60664160
https://vk.com/topic-238443049_60664865
https://vk.com/topic-238443049_60665536
https://vk.com/topic-238443049_60666201
https://vk.com/topic-238443049_60666846
https://vk.com/topic-238443049_60667410
https://vk.com/topic-238443049_60667948
https://vk.com/topic-238443049_60668471
https://vk.com/topic-238443049_60669013
https://vk.com/topic-238443049_60669649
https://vk.com/topic-238443049_60670127
https://vk.com/topic-238443049_60670611
https://vk.com/topic-238443049_60671121
https://vk.com/topic-238443049_60671553
https://vk.com/topic-238443049_60672145
https://vk.com/topic-238443049_60672707
https://vk.com/topic-238443049_60673270
https://vk.com/topic-238613049_61620133
https://vk.com/topic-238613049_61660416
https://vk.com/topic-238613049_61661015
https://vk.com/topic-238613049_61662370
https://vk.com/topic-238613049_61663127
https://vk.com/topic-238613049_61663727
https://vk.com/topic-238613049_61664344
https://vk.com/topic-238613049_61665403
https://vk.com/topic-238613049_61666396
https://vk.com/topic-238613049_61666859
https://vk.com/topic-238613049_61667466
https://vk.com/topic-238613049_61667973
https://vk.com/topic-238613049_61668424
https://vk.com/topic-238613049_61668843
https://vk.com/topic-238613049_61669431
https://vk.com/topic-238613049_61669923
https://vk.com/topic-238613049_61670528
https://vk.com/topic-238613049_61671056
https://vk.com/topic-238613049_61672040
https://vk.com/topic-238613049_61673949
https://vk.com/topic-238613049_61674520
https://vk.com/topic-238613049_61675099
https://vk.com/topic-238613049_61675713
https://vk.com/topic-238613049_61676862
https://vk.com/topic-238613049_61677472
https://vk.com/topic-238613049_61678068
https://vk.com/topic-238613049_61678633
https://vk.com/topic-238613049_61679471
https://vk.com/topic-238613049_61680104
https://vk.com/topic-238613049_61680977
https://vk.com/topic-238613049_61682733
https://vk.com/topic-238613049_61683900
https://vk.com/topic-238613049_61685288
https://vk.com/topic-238613049_61687400
https://vk.com/topic-238613049_61688091
https://vk.com/topic-238613049_61688892
https://vk.com/topic-238613049_61689625
https://vk.com/topic-238613049_61692163
https://vk.com/topic-238613049_61694912
https://vk.com/topic-238613049_61696022
https://vk.com/topic-238613049_61697404
https://vk.com/topic-238613049_61699759
https://vk.com/topic-238613049_61700290
https://vk.com/topic-238613049_61703158
https://vk.com/topic-238613049_61710898
https://vk.com/topic-238613049_61712349
https://vk.com/topic-238613049_61715121
https://vk.com/topic-238613049_61716645
https://vk.com/topic-238613049_61718235
https://vk.com/topic-238613049_61719514
https://vk.com/topic-238613049_61719966
https://vk.com/topic-238613049_61720951
https://vk.com/topic-238613049_61723091
https://vk.com/topic-238613049_61723610
https://vk.com/topic-238613049_61724095
https://vk.com/topic-238613049_61725830
https://vk.com/topic-238613049_61727910
https://vk.com/topic-238613049_61728369
https://vk.com/topic-238613049_61734596
https://vk.com/topic-238613049_61735204
https://vk.com/topic-238613049_61735918
https://vk.com/topic-238613049_61738211
https://vk.com/topic-238613049_61742986
https://vk.com/topic-238613049_61743758
https://vk.com/topic-238613049_61744456
https://vk.com/topic-238613049_61745154
https://vk.com/topic-238613049_61746305
https://vk.com/topic-238613049_61747520
https://vk.com/topic-238613049_61749937
https://vk.com/topic-238613049_61753913
https://vk.com/topic-238613049_61754322
https://vk.com/topic-238613049_61755170
https://vk.com/topic-238613049_61758587
https://vk.com/topic-238613049_61759748
https://vk.com/topic-238613049_61760124
https://vk.com/topic-238613049_61760703
https://vk.com/topic-238613049_61761029
https://vk.com/topic-238613049_61762073
https://vk.com/topic-238613049_61764542
https://vk.com/topic-238613049_61765991
https://vk.com/topic-238613049_61766666
https://vk.com/topic-238613049_61767428
https://vk.com/topic-238613049_61768459
https://vk.com/topic-238613049_61770494
https://vk.com/topic-238613049_61772768
https://vk.com/topic-238613049_61773220
https://vk.com/topic-238613049_61773366
https://vk.com/topic-238613049_61773872
https://vk.com/topic-238613049_61774188
https://vk.com/topic-238613049_61774912
https://vk.com/topic-238613049_61775489
https://vk.com/topic-238613049_61777185
https://vk.com/topic-238613049_61777359
https://vk.com/topic-238613049_61778096
https://vk.com/topic-238613049_61779337
https://vk.com/topic-238613049_61779962
https://vk.com/topic-238613049_61780146
https://vk.com/topic-238613049_61780848
https://vk.com/topic-238613049_61781349
https://vk.com/topic-238613049_61781714
https://vk.com/topic-238613049_61784007
https://vk.com/topic-238613049_61784224
https://vk.com/topic-238613049_61785616
https://vk.com/topic-238613049_61787896
https://vk.com/topic-238613049_61791261
https://vk.com/topic-238613049_61792829
https://vk.com/topic-238613049_61796205
https://vk.com/topic-238613049_61796572
https://vk.com/topic-238613049_61797600
https://vk.com/topic-238613049_61798992
https://vk.com/topic-238613049_61799871
https://vk.com/topic-238613049_61800137
https://vk.com/topic-238613049_61800423
https://vk.com/topic-238613049_61802707
https://vk.com/topic-238613049_61803481
https://vk.com/topic-238613049_61805679
https://vk.com/topic-238613049_61811434
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/70050070/viewspace-3117744/
,如需转载,请注明出处,否则将追究法律责任。