先保住已拿到的数据,再决定是否继续。限流发生时,脚本最危险的动作不是停下来,而是继续重试并把内存里未落盘的结果覆盖掉。稳妥做法是让结果先写盘、再发请求,把“已成功”和“待确认”分开存放。
两种情况的处理方向不同。暂时拒绝通常表现为短时间内连续失败,间隔后恢复;配额耗尽则可能持续返回同类错误,直到下一个周期。仅凭一次失败无法区分,需要看失败是否集中在某个时间窗、是否伴随响应头中的剩余额度提示、以及同一账号换一个入口是否仍然失败。
如果失败集中在短时间且间隔后恢复,保留已有结果并暂停重试是合理的。如果同一账号在不同任务上都失败,更可能是配额或权限问题,此时继续消耗请求只会让后续恢复更慢。注意,请求量归零本身不能证明限流已解除,也可能是脚本提前退出或目标端临时不可达。
最直接的保护动作是每完成一条就写入独立文件或追加到本地存储,而不是等全部跑完再统一输出。这样即使进程被中断,已成功的结果仍然存在。适用前提是单条结果可以独立标识,例如用查询目标加时间戳作为文件名。
具体动作:在发起请求前先记录一条“待处理”状态,收到成功响应后改写为“已完成”并写入结果体,失败则标记为“待重试”。这样做的结果是,下次启动时脚本可以只读取未完成项,而不必重新请求全部目标。下一步取决于待重试数量:如果很少,可以低频补跑;如果很多,应先确认限流原因再决定是否继续。
遇到限流时提高并发或缩短重试间隔,通常会让情况更糟。更可行的改写是加入固定间隔、减少同时进行的请求数,或把大批量拆成多个小批次分时执行。适用前提是任务本身对时效要求不高,且失败原因确实是请求过于集中。
假设一个脚本原本一次并发十个请求,限流后改为串行并每次间隔数秒,结果可能是总耗时明显增加,但已完成结果不再被反复覆盖。这个假设只用于说明取舍逻辑,实际间隔需要根据目标端的响应情况调整。如果改写后仍然失败,说明问题可能不在节奏,而在配额或权限,此时应转向退出策略。
当连续多次失败、且失败原因指向配额耗尽或权限不足时,继续运行只会产生更多无效请求。此时应停止脚本,保留当前结果和待处理清单,等下一个周期或确认权限后再继续。适用前提是你能接受任务延后,并且已有结果足以支撑当前判断。
退出不等于放弃。把待处理清单单独保存,并记录最后一次成功的时间和失败类型,可以让下一次启动更有依据。如果已有结果已经覆盖了关键样本,也可以先基于这部分结果做判断,把剩余目标留到后续补齐。
限流缓解后,不要直接从头重跑。先读取本地已完成记录,跳过已成功项,只补跑待处理项。核对时重点看三件事:已完成结果是否完整、待处理项是否有重复标识、失败类型是否与上次一致。这些检查能避免把已经拿到的结果再次覆盖,也能防止在配额未恢复时重复消耗。
如果目标端返回的错误信息不足以判断原因,可以先用少量请求试探,而不是一次性恢复全量。试探成功再逐步放开,失败则回到退出状态。整个过程的核心是让已有结果的保存独立于请求是否成功,这样限流只影响进度,不影响已经拿到的部分。