ITPub博客

首页 > 应用开发 > Java > java编写一个接口限流器(IP + 时间窗算法)

java编写一个接口限流器(IP + 时间窗算法)

原创 Java 作者:tiannuo 时间:2026-05-13 14:35:06 0 删除 编辑

一、设计思路(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/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论

注册时间:2026-05-08

  • 博文量
    74
  • 访问量
    66702