结论先说:如果脚本已经拿到一部分可交付结果,遇到限流时应优先“冻结并落盘已有结果”,而不是立即重试或换用更激进的调用方式。冻结的含义是停止继续请求、把已取得的数据按批次写入本地或独立存储,并记录每个批次的完成边界。只有在确认限流属于短时波动、且未完成部分可以低成本补齐时,才值得考虑继续调用。否则,继续重试往往会让已有结果也陷入不确定状态。
限流通常发生在调用侧,但影响面不同。若脚本是边请求边写入,限流会导致写入中断,已写入的部分可能缺少批次标记;若脚本是先全部请求、再统一写入,限流时内存中的结果可能尚未持久化,一旦进程退出就会丢失。两种情况下,保护动作不同。
实际动作:在脚本里增加一个“限流即落盘”分支,捕获到限流响应后先调用一次写入函数,再退出或休眠。这个动作的结果是,你下一步可以基于明确的断点决定是补齐还是放弃,而不是面对一个不确定的内存状态。
遇到限流时,常见选择是继续重试,或者换用另一种调用方式。两者都有成立条件,也都有代价。
限流是短时的、未完成部分规模小、且重试间隔足够长。此时可以保留已有结果,只对失败批次做有限次重试。代价是时间不可控,如果限流持续,重试会反复消耗配额,甚至让已有结果无法及时交付。
你确认另一种调用方式走的是不同配额或不同接口,且返回字段与已有结果口径一致。代价是两批数据的口径可能不同,合并时需要额外对齐字段、时间范围和去重规则。如果口径不一致,切换反而会污染已有结果。
一个假设例子:脚本已成功获取前 40 条记录,第 41 条开始返回限流。若未完成部分只有 10 条,且限流提示的等待时间很短,继续重试的代价更低;若未完成部分有 500 条,且限流没有明确恢复时间,切换调用方式或改为分批隔日补齐更合理。这里的数字只用于说明比较方法,不代表任何真实工具的实际限额。
如果已有结果本身依赖一次完整调用才能成立,例如结果需要全量排序、去重或跨批次聚合,那么冻结部分结果可能没有独立交付价值。此时保护已有结果的正确动作不是落盘,而是先确认已取得的部分是否可单独使用。若不可单独使用,应记录已完成批次和缺失范围,等限流解除后从缺失范围补齐,而不是把半成品当作最终结果交付。
另一个反例是:限流由脚本自身触发的并发过高导致,而非外部配额耗尽。此时冻结已有结果后,降低并发、拉长间隔再继续,通常比换调用方式更有效。判断依据是限流是否随并发下降而消失;如果下降后仍持续,才更可能是外部配额问题。
无论选择哪种做法,下一步都应先建立断点记录,再决定补齐策略。断点记录至少包含:已成功批次的标识、最后成功时间、失败起始位置、失败原因分类。补齐策略则根据未完成部分的规模和口径一致性来选择。
这样做的结果是,限流不再直接威胁已有结果,你也能根据断点记录判断是继续补齐还是调整调用策略。对搜索引擎推广软件这类需要持续取数的工具来说,保护已有结果的关键不是避免限流,而是让限流发生时已有结果仍然可交付、可续接。