结论先说:限流发生时,最该保护的不是“继续跑完”,而是已经拿到的原始响应和它的取得时间。只要把原始结果落盘、把未完成项标记为待补,你就有机会在限流解除后只补缺口,而不是整批重跑。是否值得补,取决于这批数据是用于一次性判断,还是会被反复引用;前者可以放弃尾部,后者应优先保住结构完整。
限流本身不区分数据价值,但你的处理方式必须区分。可以把已有结果分成两类:一类是一次性判断型,比如临时核对一批页面的状态,看过结论后原始明细很少再回查;另一类是长期引用型,比如要沉淀成内部对照表、后续会按批次比较变化。两者的取舍完全不同。
一次性判断型遇到限流,合理动作是:立即停止新请求,把已返回的部分按原顺序保存,并记录“第几项之后缺失”。如果缺失集中在尾部且不影响结论方向,可以直接用现有样本下判断,把缺失部分标注为未覆盖。长期引用型则不能这么处理,因为缺一段的对照表在几周后会变成误导,此时应优先保留请求参数、时间戳和原始响应体,宁可这次不完成,也不要用不完整数据覆盖旧版本。
很多脚本的问题不是被限流,而是被限流时结果还在内存里,进程一退就全丢。可执行的顺序是:捕获限流信号后,先写出已完成部分,再写一个状态文件,最后才决定是否重试。
做完这一步再评估:限流是短时突发还是持续状态。短时突发可以安排延迟重试;持续状态说明当前节奏超出对方承受范围,继续硬跑只会拉长被封时间,此时应降低并发或改为分批。
保留适用于结果仍会被引用、且缺失部分可以事后补齐的情况。前提是你有稳定的任务标识,补跑时能精确对上缺口。若任务本身是一次性生成的随机列表,补跑无法对应,保留的价值会大打折扣。
改写适用于原始结果粒度太细、限流后无法拿全的情况。比如原本想逐条采集,现在只能拿到汇总层。此时可以把目标从“逐条完整”改成“抽样加汇总”,但要在结果里注明覆盖范围和抽样方式,否则后续使用者会误以为这是全量。
退出适用于两类情形:一是这批数据只服务于一个即将失效的旧系统或旧合作关系,继续投入没有下游;二是限流反复出现且对方没有可用接口,继续绕行会带来合规和稳定性风险。退出的正确姿势不是删掉脚本,而是把已得结果归档,并记录“为何停止、停在哪一步”,方便以后有人问起时不必重新踩一遍。
假设你要核对 500 条旧链接,脚本跑到第 180 条时开始返回限流。此时先看缺口分布:如果 1 到 180 是连续成功、之后全部失败,说明限流发生在中途,前 180 条可信,补跑从第 181 条开始即可。如果失败是零散穿插在前 180 条里,那前 180 条本身就不完整,不能当作“已完成部分”直接使用,需要先按待补清单回补,再谈整体结论。
这个判断直接影响下一步:连续缺口对应“补尾部”,零散缺口对应“先校验再补”。两者花费的时间不同,对结论可信度的影响也不同。数字只用于说明比较方法,实际任务量以你自己的清单为准。
补跑前,确认待补清单里的标识与原始结果一一对应,并确认限流是否已缓解。补跑后,不要只看“数量补齐了”,还要抽查几条补跑结果与原始结果的字段结构是否一致;限流期间对方返回的错误页有时会被脚本误当成正常内容存下来,这类污染比缺数据更难发现。
如果补跑再次触发限流,说明当前节奏仍不合适,应转为更低频的分批处理,或接受部分缺失并在结果中明确标注。把“已覆盖范围”写进结果说明,比追求表面上的 100% 完成更能保护后续决策。