Java限流核心是拦截+计数+判断,推荐Spring AOP+Redis实现跨服务共享限流,Guava适用于单机低QPS场景,Filter/Interceptor更灵活可定制,生产需配置化、降级与监控。

Java中实现接口访问次数限制,核心是“拦截请求 + 计数存储 + 规则判断”,不依赖框架也能做,但结合Spring Boot会更简洁高效。关键不在代码多寡,而在计数粒度(用户/IP/接口)、存储选型(内存/Redis)和限流策略(固定窗口/滑动窗口/令牌桶)是否匹配业务场景。
基于Spring AOP + Redis的通用限流模块
适合中高并发、需跨服务共享计数的场景。用AOP切面统一拦截带限流注解的方法,Redis存储计数并利用其原子操作避免并发问题。
- 定义自定义注解:red">@RateLimit(maxCount = 100, timeWindowSeconds = 60),标注在Controller方法上
- AOP切面捕获请求:提取标识符(如
request.getRemoteAddr()或Authentication.getName()),拼接Redis Key(如"rate:ip:192.168.1.100:60s") - 用
redisTemplate.opsForValue().increment(key)原子递增,并设置过期时间(expire(key, 60, TimeUnit.SECONDS)) - 若返回值 > maxCount,抛出
RuntimeException("访问过于频繁"),由全局异常处理器返回429
轻量级内存限流(Guava RateLimiter)
适合单机部署、QPS不高、对精度要求不严的内部接口。无需外部依赖,启动快,但无法集群共享状态。
- 为每个需限流的接口初始化一个
RateLimiter实例(如RateLimiter.create(10.0)表示10 QPS) - 在方法入口调用
rateLimiter.tryAcquire(),返回false则拒绝请求 - 注意:不要在每次请求都新建RateLimiter,应作为类成员或Spring Bean管理
- 缺点:重启丢失状态;不同实例间无法协同;不支持按用户/IP区分粒度
基于Filter或Interceptor的请求级控制
适用于需要深度定制拦截逻辑(如读取Header、动态计算key、组合多条件限流)的场景,比AOP更底层、更灵活。
免费 盛世企业网站管理系统(SnSee)系统完全免费使用,无任何功能模块使用限制,在使用过程中如遇到相关问题可以去官方论坛参与讨论。开源 系统Web代码完全开源,在您使用过程中可以根据自已实际情况加以调整或修改,完全可以满足您的需求。强大且灵活 独创的多语言功能,可以直接在后台自由设定语言版本,其语言版本不限数量,可根据自已需要进行任意设置;系统各模块可在后台自由设置及开启;强大且适用的后台管理支
立即学习“Java免费学习笔记(深入)”;
- 写一个
OncePerRequestFilter,在doFilterInternal中解析请求路径、参数、Header等 - 构造唯一限流Key(例如
"user:" + userId + ":api:/order/create") - 查Redis或本地缓存(如Caffeine)获取当前计数,判断是否超限
- 可叠加多层规则:先IP限流,再用户限流,最后接口总限流,用责任链模式组织
配置化与降级兜底设计
生产环境不能硬编码限流值,必须支持动态调整和失效自动恢复。
- 限流参数(maxCount/timeWindow)从Nacos/Apollo/ZooKeeper加载,监听变更实时刷新内存中的规则Map
- Redis不可用时自动降级:记录日志 + 切换为本地Guava限流(或直接放行,避免雪崩)
- 添加监控埋点:统计被限流次数、各接口命中率,接入Prometheus+Grafana看板
- 对登录、短信发送等敏感接口,建议加验证码或人机识别二次校验,避免单纯靠频次防御
基本上就这些。没有银弹方案——简单项目用Guava够用,微服务架构优先选Redis+AOP,安全要求高的补上风控策略。关键是把“谁在调用”“怎么算一次”“超了怎么办”这三件事定义清楚,再选工具落地。









