先给结论:限流发生时,最该保护的往往不是“继续拿新数据”,而是“让已经拿到的数据可续跑、可对账、可交付”。做法是把每次查询的原始返回、请求参数和分页游标落盘成一条条可追溯的记录,再让脚本按“已确认完成”的标记跳过重复请求。这样即使工具中途拒绝服务,你也能从断点继续,而不是重跑全部并再次触发限流。
同样表现为请求失败,处理方式完全不同。判断依据不是错误码本身,而是它出现的形态:
这三种情况对“已有结果”的影响不同。暂时拒绝只影响进度;配额耗尽要求你保留进度并等待;来源受限则意味着继续重试可能让状态更糟,此时应停止自动重试,转为人工核对。若只看单次失败就判定“被封”,容易误判,因为网络抖动、目标页面结构变化也会产生类似错误。
保护结果的核心是让每条记录自带“是否完整”的状态,而不是只存一份最终汇总。以你手上正在跑的一个查询任务为例,可以按下面的顺序改造:
done、partial 或 failed。done 的单元发起请求。这个动作的直接结果是:重跑次数从“全部单元”降到“未完成单元”。对限流场景而言,这决定了你下一轮请求量的大小,也决定了是否还有机会在配额内补齐缺口。
很多脚本在失败后会立即重试,这恰恰是让已有结果变得不可信的原因——你无法区分哪些数据是干净的,哪些是在压力下凑出来的。更稳妥的顺序是:
done、partial、failed 各有多少。partial 和 failed 开始,而不是从头。这里有一个容易忽略的边界:如果工具返回的是“部分页面内容 + 错误提示”,这条记录不能标成 done。把它标成完成,后续汇总会把残缺数据当成完整数据,错误会一路传到交付物里。此时应标 partial,并在备注里写明缺失的是哪一页或哪个字段。
假设你手动测试了 5 个关键词,全部成功,于是写脚本批量跑 2000 个。脚本前 300 个正常,之后开始大量失败。这个现象不能直接归因于“工具不支持批量”,因为手动测试和脚本请求在频率、并发、请求间隔上并不相同。
此时可执行的对照是:把脚本并发降到 1,请求间隔拉长,只重跑失败的 1700 个中的一小段。如果这一小段成功率恢复,说明问题更可能在请求节奏;如果仍然稳定失败,则更可能是配额或来源限制。这个判断只用于决定下一步是调参还是等待,不能反过来证明工具本身的能力边界。
在把结果交给执行人员之前,至少确认三件事:状态记录里没有未处理的 partial;失败单元有明确的失败原因分类,而不是统一写成“请求失败”;原始记录与汇总结果能对得上条数。若做不到第三点,说明中间有覆盖或去重逻辑吃掉了数据,此时应先修脚本再交付,否则接收方无法判断哪些结论有数据支撑。
限流本身不一定会毁掉已有结果,真正让结果失效的是缺少状态标记和断点续跑能力。把这两点补上,限流就只是进度问题,而不是数据可信度问题。