限流方案容易从工具列表开始:Sentinel、Bucket4j、Guava RateLimiter、Nginx、Kong、Tyk、Traefik、网关自研。真正选型时,先别急着挑工具,要先问限流发生在哪里:单应用、单接口、单用户、单 IP、全站入口,还是跨服务的集群限流。
先分清限流位置
常见位置有三层:
- 应用内限流:代码里按注解、拦截器或 AOP 限制接口。
- API 网关限流:统一入口按路径、IP、用户、租户做限制。
- 基础设施限流:Nginx、Ingress、WAF、CDN 在更前面挡流量。
应用内限流最懂业务,但每个应用都要接入。网关限流统一,但不一定知道业务细节。基础设施限流最靠前,适合挡明显异常流量,但很难做复杂业务规则。
Sentinel 适合什么场景
Sentinel 的价值不只是限流,还包括熔断降级、系统保护、热点参数、实时监控和规则配置。它适合 Java 微服务体系里做服务保护。
常见概念:
- QPS 限流:每秒通过请求数。
- 并发线程数限流:保护慢接口占满线程。
- 熔断 RT:响应时间过高时触发熔断。
- 异常比例/异常数:错误率过高时降级。
- 热点参数:按某个参数值单独限流。
如果系统已经是 Spring Cloud / Dubbo Java 体系,Sentinel 接入成本相对可控。如果只是一个小博客或轻量工具,完整上 Sentinel Dashboard、规则持久化和控制台,可能偏重。
简单系统可以先用注解和缓存
很多个人项目或中小后台,先做轻量限流就够用:
- 单 IP 每秒最多 N 次。
- 登录接口单 IP / 单账号限制。
- 搜索接口限制更严格。
- 后台写接口限制频率。
- 黑名单和白名单预留。
实现上可以用拦截器或 AOP 读取注解,再用本地缓存或 Redis 计数。
示例思路:
key = rate_limit:{ip}:{path}:{window}
count = incr(key)
expire(key, 1s)
count > threshold => reject
单机项目用本地缓存就够;多实例部署时,用 Redis 统一计数。
网关限流解决统一入口
如果服务已经有统一网关,限流放网关会更清晰。网关可以在请求进入业务服务前就拒绝,减少后端压力。
适合放网关的规则:
- IP 维度限流。
- 路径维度限流。
- 用户或 token 维度限流。
- 全局 QPS 保护。
- 明显异常流量阻断。
不太适合放网关的规则:
- 依赖复杂业务状态。
- 需要数据库事务参与。
- 不同租户有细粒度动态策略。
这些规则可以由业务服务判断,或由网关调用配置中心后执行。
限流要配套观测
没有观测的限流,很容易变成“用户说访问不了,后端说没问题”。至少要记录:
- 命中的限流规则。
- 被限流的 IP、用户、路径。
- 当前阈值和计数。
- 返回状态码。
- 是否误伤。
返回给前端时,建议使用明确状态码和提示,例如 429 Too Many Requests。后台日志则记录详细原因,方便调整阈值。
最后抓住一句话
限流选型先看位置,再看复杂度。小系统可以用注解 + 本地缓存或 Redis;微服务体系可以考虑 Sentinel;统一入口流量优先放网关。不要为了一个简单接口,一上来就把整套网关和控制台都搬进来。




