限流发生时,最先要做的不是重试,而是判断已有结果属于哪一类:可重复获取的中间数据,还是重跑成本很高的最终产物。两类结果的保护策略不同。如果结果可以低成本重算,重点放在控制重试节奏;如果重算要消耗大量配额或人工校验,重点放在落盘和断点续跑。下面按这两种条件分别展开。
当脚本抓取的是公开列表、批量查询结果这类可重复获得的数据时,限流本身不是灾难,真正的损失是把剩余配额浪费在无效重试上。此时保护已有结果的动作是:把已成功返回的条目立即写入本地文件或数据库,而不是攒在内存里等全部跑完再统一保存。
具体做法是每处理完一批就追加落盘一次,并在文件里记录已完成的游标或主键。这样即使进程被杀掉,下次启动时读取最后一条记录的位置就能续跑。判断是否属于这种情况的依据是:同一请求隔一段时间再发,返回内容基本一致,且单次请求成本低。
一个假设的例子:某脚本需要分页拉取一千条记录,跑到第三百条时开始返回限流提示。如果每页结束就落盘,重启后从第三百零一条继续,损失只有等待时间;如果全部结果都留在内存,进程退出后前面三百条也要重来,等于把已经花掉的配额又花一遍。
如果已有结果包含人工标注、跨系统拼接或长时间计算的产物,重跑不只是时间问题,还可能引入不一致。这时遇到限流的正确动作是停止新的调用,把当前结果完整导出并标记状态,再单独评估剩余部分是否值得继续。
冻结动作包括三步:导出当前结果到独立文件并注明生成时间;记录哪些条目已完成、哪些缺失;把脚本的调用入口暂时关闭,避免自动重试覆盖或污染已有数据。完成冻结之后,再判断剩余缺口能否用其他方式补齐,比如改用离线数据、延后处理,或者只补关键字段。
判断依据是:缺失部分是否影响最终结论。如果缺失的是边角字段,冻结后的结果可能已经够用;如果缺失的是核心指标,才需要重新申请配额或调整调用方式。
收到限流提示或请求量骤降,不能直接断定是调用频率过高。以下原因都会产生类似现象:
区分方法是看错误返回的具体内容、发生的时间分布,以及换一个低频率的单独请求是否同样失败。如果单次低频请求正常,问题更可能在并发控制;如果单次也失败,要先排查鉴权和参数,而不是继续降低频率。把请求量归零当作限流已解除的证据并不成立,它也可能只是脚本已经停止发送。
无论属于哪种条件,都可以先做一个动作:在脚本里加入落盘检查点,并让重试逻辑读取检查点而不是从头开始。这一步的结果会直接改变下一步的选择——如果检查点机制生效,重启后只补缺失部分,配额消耗可预测;如果发现落盘的数据本身不完整或格式错乱,说明问题出在写入环节,需要先修复存储逻辑,再谈重试策略。
对于重算代价高的结果,还要额外做一次校验:把冻结的数据与限流前最后一次成功返回的结果对比,确认没有在异常状态下写入半成品。校验通过后再决定是否继续调用;校验不通过,应回退到上一个可信版本,而不是在污染数据上继续叠加。
有两种情况应放弃已有结果重新开始。一是数据有时效性,冻结期间源数据已经变化,续跑会得到新旧混杂的结果;二是限流原因是账号或权限被调整,继续使用旧结果可能基于已经失效的授权,后续核对会更麻烦。这两种情况下,保留旧结果反而增加判断成本,不如在确认新的调用条件后整体重跑。
是否保留,取决于结果的一致性和时效要求,而不是取决于已经花了多少时间。已投入的成本不构成继续使用失效数据的理由。