public class SlidingWindowRateLimiter { private final int windowSize; // 窗口大小(秒) private final int limit; // 窗口内允许的请求数 private final AtomicInteger[] window; // 窗口内请求计数 private int currentIndex; // 当前窗口索引 private final ScheduledExecutorService scheduler; public SlidingWindowRateLimiter(int windowSize, int limit) { this.windowSize = windowSize; this.limit = limit; this.window = new AtomicInteger[windowSize]; for (int i = 0; i < windowSize; i++) { window[i] = new AtomicInteger(0); } this.currentIndex = 0; this.scheduler = Executors.newScheduledThreadPool(1); startWindowSliding(); } private void startWindowSliding() { scheduler.scheduleAtFixedRate(this::slideWindow, 1, 1, TimeUnit.SECONDS); } private void slideWindow() { currentIndex = (currentIndex + 1) % windowSize; // 移动窗口 window[currentIndex].set(0); // 清空新位置的计数 } //方法用于检查当前窗口内的请求次数是否超过了限制。如果未超过限制,则允许新的请求并在当前位置增加计数;否则,拒绝请求。 public boolean allowRequest() { int totalRequests = 0; for (AtomicInteger count : window) { totalRequests += count.get(); // 计算窗口内总请求数 } if (totalRequests < limit) { window[currentIndex].incrementAndGet(); // 在当前位置增加计数 return true; // 允许请求 } return false; // 请求超限 } public void stop() { scheduler.shutdown(); } public static void main(String[] args) { SlidingWindowRateLimiter rateLimiter = new SlidingWindowRateLimiter(10, 10); // 窗口大小为 10 秒,限制为每秒最多 10个请求 for (int i = 0; i < 20; i++) { if (rateLimiter.allowRequest()) { System.out.println("Request " + (i + 1) + " is allowed."); } else { System.out.println("Request " + (i + 1) + " is rejected."); } try { Thread.sleep(300); // 模拟请求到达间隔 } catch (InterruptedException e) { e.printStackTrace(); } } rateLimiter.stop(); // 停止限流器 } }
简单时间窗口限流
最新推荐文章于 2024-04-27 17:30:34 发布