应构建分层限速机制:nginx层按ip+路径限流为第一道防线;应用层按用户id或token精准限速防绕过;网关层统一管控并支持动态规则;配套人机验证、二次确认、日志告警及降级兜底。

要防止业务接口被暴力枚举(如登录爆破、验证码滥刷、优惠券批量领取等),不能只靠应用层单点限流,必须构建分层、精准、可落地的请求限速机制。核心思路是:在流量入口处拦截,按业务维度设限,兼顾防绕过与降级容错。
一、Nginx 层限速:第一道防线(推荐优先启用)
这是最轻量、最高效、不侵入业务代码的方案,适用于所有 HTTP 接口。
-
按 IP + 接口路径组合限速(防单 IP 扫描)
在nginx.conf的http块中定义:limit_req_zone $binary_remote_addr$uri zone=enum_limit:10m rate=3r/s;
-
$binary_remote_addr$uri确保同一 IP 访问不同接口(如/login,/sms/send)各自独立计数 -
rate=3r/s表示每秒最多 3 次请求,适合登录/短信类敏感接口
-
-
在对应 location 中启用并设置突发缓冲
location /api/login { limit_req zone=enum_limit burst=5 nodelay; limit_req_status 429; proxy_pass http://backend; }-
burst=5允许短时突发(如用户手抖连点),但nodelay防止排队堆积,直接拒绝超限请求 - 返回
429 Too Many Requests,前端可据此提示“操作太频繁”,避免暴露后端逻辑
-
✅ 生产建议:对
/api/sms/send、/api/login、/api/coupon/grab等高风险路径单独配置更严规则(如1r/s),并配合limit_conn控制并发连接数(防 Slowloris 类慢速攻击)。
二、应用层限速:按业务身份精准控制(防 IP 轮换)
单靠 IP 限速易被代理池、IP 池绕过。需升级到用户级或凭证级限速:
-
按用户 ID 或 Token Hash 限速(需后端解析请求头)
示例(Spring Boot + Redis):String key = "rate:uid:" + userId; // 或 "rate:token:" + DigestUtils.md5Hex(token) Boolean allowed = redisTemplate.execute(rateLimiterScript, Collections.singletonList(key), "10", "60" // 10次/60秒 ); if (!allowed) throw new BusinessException("请求过于频繁"); -
关键细节:
- 使用滑动窗口(如 Redis ZSet 实现)比固定窗口更公平,避免“整点突刺”问题
- Key 中加入业务标识,如
rate:login:uid:123和rate:sms:ip:192.168.1.1分开统计 - 限流失败时返回明确错误码(如
429)和Retry-After头,便于前端退避重试
三、网关层统一管控(适合微服务架构)
若使用 Spring Cloud Gateway 或 API 网关,应在网关侧集中配置,避免每个服务重复实现:
-
基于请求路径 + 请求参数组合限流
例如限制/api/v1/coupon?code=xxx的调用频次,防止通过改参绕过 - 支持动态规则热更新(如从 Nacos 或数据库加载),便于运营实时封禁异常行为
- 自动联动风控系统:当某用户连续触发限流,自动标记为“可疑”,触发图形验证码或人工审核
四、配套加固措施(不能省)
限速不是万能的,必须配合以下手段才能真正防住暴力枚举:
-
敏感接口强制人机验证
登录、发短信前插入极验、腾讯云验证码等,成本低、识别率高 -
关键操作二次确认
如领取优惠券后需短信/邮箱确认,增加攻击者自动化成本 -
日志与告警联动
对高频触发限流的 IP 或用户,实时写入 ELK 并推送企业微信告警,便于人工介入 -
降级兜底
限流触发后,返回友好提示而非空响应或 500 错误;极端情况下可关闭非核心功能(如暂停发券)保主链路
不复杂但容易忽略











