答案取决于你手里那批结果是否可重放:如果脚本每次都能从同一批输入重新取数,限流时优先保进度,把断点记下来,等窗口恢复再续跑;如果取数有先后依赖、或上游数据本身在变,优先保结果,把已取回的原始响应完整落盘,宁可停在半途,也不要让脚本带着残缺状态继续写库。判断依据是重跑成本和数据时效,不是限流提示本身。
可重放的意思是:同样的输入列表,过一段时间再调一次,得到的仍然是可用的结果。批量查询固定词表、拉取历史存档、按ID逐条取详情,通常属于这一类。此时限流只是时间问题,进度可以牺牲。
不可重放的情形更常见于工具与查询场景:结果里混入了当时才有的状态,比如某条记录的当期排序、当期可见字段、当期关联关系;或者脚本内部做了多步转换,中间态没有单独保存。这类任务一旦被限流打断,重跑不只是慢,而是拿不回同一批数据。
一个简单的自检:把输入列表原样再跑一遍,你能否接受新结果覆盖旧结果?能接受,按可重放处理;不能接受,按不可重放处理。这个判断必须在写脚本之前做,限流发生后再想就晚了。
选择保进度的前提是输入集合稳定、结果允许被后一次覆盖。此时限流的正确反应是暂停而不是降速硬扛。
实施动作按顺序做三件事。第一,把当前已完成的输入项写入一个独立的进度文件,只记标识,不记结果,写成功后再继续。第二,遇到限流响应时立即停止本轮,不要在同一窗口内换IP或换账号重试,这类绕过会让后续判断失去依据。第三,把限流发生的时间、已处理数量、剩余数量记进日志,作为下一次启动的起点。
这样做的结果是:下一次运行只处理剩余部分,已取回的结果不必重新请求。代价是总耗时拉长,但结果集的完整性不受影响。如果限流窗口较长而任务总量不大,也可以选择整批重跑,前提是你能确认上游数据在这段时间内没有变化。
例外情况:如果脚本写库是逐条覆盖而不是追加,断点续跑反而可能造成同一记录的多次写入。此时应改为先落盘、后统一入库,把网络请求阶段和写库阶段分开。
选择保结果的前提是数据有时效性或依赖顺序。这时限流是危险信号,因为等待期间上游可能已经改变。
实施动作的核心是让每一次成功响应都先成为文件,再成为数据库记录。原始响应按输入标识命名保存,转换逻辑放在读取文件之后。限流发生时,脚本停在当前项,已经落盘的部分原样保留,不做任何清理。
判断是否要继续的判断依据是:剩余项是否依赖已失败项的输出。如果依赖,整个批次标记为不完整,不要对外发布部分结果;如果不依赖,可以只发布已完成部分,并在结果中标注缺失范围。
假设一个场景:脚本按顺序取100条记录,每条记录的处理需要用到上一条的某个字段。取到第40条时限流。此时前39条的结果是有效且不可再生的,第40条之后全部作废。正确动作是保存前39条并把任务标记为中断,而不是从第40条重试,因为重试时上一条的字段可能已经变化。这个例子只用于说明判断方法,不代表任何具体工具的行为。
限流发生时再决定存什么,通常已经丢了一部分。提前约定两件事可以省掉大部分麻烦。
恢复时的动作是:先读进度文件或扫描已落盘文件,算出缺口,再只请求缺口部分。如果缺口跨越了限流窗口,先做一次小批量试探,确认接口已恢复再放开全量。
请求量归零、日志里不再出现限流字样、脚本正常退出,这些都可能有别的解释:任务本来就已经跑完、脚本在异常分支里静默退出、或者限流被上游以其他形式返回而没有触发你的判断逻辑。
要确认结果完整,需要比对三组数字:输入总数、成功落盘数、入库数。三者一致才说明没有丢项。如果只看请求量下降就认为问题解决,很可能把一批失败项当成了已完成项。
另外,限流阈值和窗口长度属于具体工具的运行参数,不同工具、不同账号、不同时段都可能不同,需要以实际返回为准,不要按固定值设计重试节奏。涉及具体工具的功能和限制,应查阅其当前文档核对。