你可能见过这些场景:
接口明明是为了防刷加了限流,结果是真人老被拦,脚本反而绕来绕去还能混过去。
登陆页面里,正常用户多输几次密码就被提示稍后再试;支付接口上,同一张卡连续两笔正常订单被挡在风控前面;后台操作时,客服高峰处理工单各种报错请稍候重试。
问题往往不在限流有没有,而在限流规则配得太粗,只按次数和时间一刀切,把一些典型的正常行为直接归类成异常。
这篇文章想讲清三件事:
一是限流配粗后常见的误伤表现;
二是这些误伤背后的规则设计问题;
三是应该怎么重写限流策略,既挡掉真正的异常流量,又尽量不伤到正常用户。
================================
一、常见误伤:限流到底在“误伤”谁
1、操作稍微密一点就被踢出
几类典型情况:
- 登陆场景
用户输错一次密码,立刻再试几次就触发防暴力破解,被要求隔一段时间再登陆。 - 支付场景
同一个人分批下几单,填完信息连点几次支付,从第三单开始就提示稍后再试。 - 后台场景
客服在处理列表时连续点击下一条,接口直接返回限流错误,页面频繁刷新。
从机器视角看,这些操作频率确实不低;但从人的视角看,只是集中处理任务。粗粒度限流看不懂这个差异,于是统统当成风险流量。
2、不同用户被一刀切对待
还有一种更隐蔽的情况:
- 新用户刚注册想多浏览几页,频繁碰到访问过于频繁提示;
- 老用户在活动期频繁比价和下单,高价值用户反而比普通用户更容易撞上限流;
- 公司内部同事在固定时间批量导出报表,经常被系统当成异常访问。
限流规则只按某接口在某时间窗口内,同一用户或同一来源最多允许多少次请求,没有任何用户画像和历史行为概念。高价值老用户和刚来的脚本,在规则眼里没有区别,自然容易误伤重要用户。
================================
二、设计问题:规则太粗看不懂真实行为
1、只看频率不看模式
很多限流规则只有两项内容:窗口时间和最大次数。这样设计完全不考虑:
- 操作顺序是否符合常见路径
正常用户一般是先浏览详情再加入购物车再下单,而脚本可能直接高频打下单接口。 - 操作间隔是否像人类
真人操作有犹豫和思考,不会做到几百次请求间隔极度平均。 - 接口本身的使用节奏
搜索提示类接口天然频次高,修改密码这类接口天然频次低。
频率一超就挡,不区分模式,自然会把一部分正常操作当成攻击。
2、时间窗口不贴业务节奏
时间窗口相关的两个常见问题:
- 窗口过短
用户在几十秒里连续完成几步操作,很容易打满上限,被迫等下一轮窗口,体验非常差。 - 窗口过长
用户在极短时间里操作比较密集,后面很长一段时间内都处在限流状态,正常使用被拖累。
很多团队直接采用统一窗口值,如每分钟、每小时,所有接口共用同一套配置,不看业务节奏,不看接口特征,也不看高低峰时段,结果只能写得非常保守。
3、没有用户分层,贵客和脚本同待遇
限流本质是保护资源,而不是简单地挡请求。如果没有最基本的分层:
- 是否已登录;
- 是否有长期正常历史;
- 是否属于高价值老用户;
- 是否来自可信网络环境。
那规则只能按最危险的情况来写。高价值用户的体验被迫跟着一起降低,这就是粗限流带来的隐性代价。

================================
三、重写策略:限流粒度要对齐业务
1、按接口类型拆开限流维度
不要只写一条总规则,至少拆成几类接口:
- 浏览类接口
商品详情、列表浏览、搜索建议,允许更高的频率,可以重点监控来源数量和访问路径。 - 写操作接口
创建订单、修改资料、提交工单,需要限制单用户单位时间内的次数,同时控制单设备和单出口的并发。 - 高敏感接口
登陆、重置密码、支付验证,除了频率,还要看失败次数和行为组合,比如短时间内连续失败、高危地区反复尝试等。
这样同样是每秒十个请求,打在不同接口上的含义完全不同,规则也应该不同。
2、按用户分层配置不同阈值
可以先做一版简单分层:
- 访客
没有登录,只能访问有限的接口和频率。 - 新用户
注册时间短,允许较高的浏览频率,但写操作仍需保守。 - 普通老用户
有一定正常历史,浏览和轻量写操作应更宽松。 - 高价值用户
充值多、订单多、历史记录干净,高峰期应尽量保证体验。
对应的策略可以是:
- 对访客
更严格地控制访问总量,多使用简单验证码。 - 对新用户
浏览接口开得较宽,登录和密集写操作要保守。 - 对普通老用户
适当提高各类阈值,避免轻易挡住正常使用。 - 对高价值老用户
触限后优先引导增强验证,例如简单二次确认,而不是直接拒绝服务。
这样一来,大促期间高价值用户连续比价和下单时,就不会和毫无历史的新账号享受同一套粗暴规则。
3、把错误处理和重试纳入限流设计
限流触发后的处理方式也很关键,如果只是一刀切返回错误,再加上统一的自动重试,很容易把本来有限的问题放大。
可以按任务重要程度拆分:
- 高优业务
下单、支付、关键配置修改,被限流时优先排队或进入缓冲队列,重试间隔逐步拉长,多次失败需要告警人工介入。 - 中等业务
报表、查询,可以提示稍后重试,重试次数有限,避免长时间堆积。 - 低价值任务
例如某些采集,当前时段被限流就记录为失败,留到下一批任务再补,不要在高压时段反复撞同一条线。
把限流、错误处理和重试当成一件事来设计,而不是三个互相冲突的模块,系统在高峰下的表现会稳定很多。
================================
四、落地建议:先改一条链路再推广
真正改动时,不用一上来就搞全系统,可以按成本最低的方式推进:
1、先挑一条抱怨最多的链路
一般是登陆或下单,把这条链路过去一段时间的访问分布拉出来,看:
- 不同时段的请求量变化;
- 不同用户类型的访问分布;
- 限流相关的错误率。
2、在这条链路上试点分级限流
先做这些调整:
- 拆分不同接口,浏览、写入、验证分别限流;
- 给访客、新用户、老用户、高价值用户设不同阈值;
- 对支付等关键操作增加柔性排队策略,而不是直接拒绝。
3、对比前后效果
重点看三项变化:
- 限流相关错误总数是否下降;
- 高价值用户投诉是否明显减少;
- 高峰时间段系统资源占用是否更平滑。
如果效果明显,再把同样的结构复制到后台操作、报表查询、内部工具等其他链路上。
================================
五、借助易路,让限流策略和出口资源配合起来
限流要做好,除了规则本身,还离不开出口资源的配合。很多团队到最后会发现,问题根本不只是规则写得粗,还在于不同任务混用同一批代理出口。
如果你已经在用易路代理作为统一出口层,可以顺手把限流策略和线路分组绑在一起:
- 为不同业务建不同线路组
例如把登录和支付绑定在一组更稳的住宅线路上,把采集和低优任务集中在一组机房线路上,让规则和线路质量对齐。 - 在面板里按线路组看成功率和延迟
哪一组线路在高峰期表现变差,可以快速看出来,方便你判断是限流配置太松,还是某个出口池本身撑不住。 - 用标签而不是具体地址接入
应用侧只引用例如登陆出口、采集出口这样的标签,后续在易路后台调整线路和扩容,不需要一遍遍改代码。
限流规则定清楚,再配合出口分池和资源配额,你的系统就不再靠硬扛和运气,而是靠一套可解释、可调优的结构来抗高峰。