先保已有结果,再谈重试。更准确地说:如果脚本已经把部分查询结果写入本地,限流发生后应立刻停止继续调用,把已落盘的数据冻结成一份带时间戳的快照,然后才决定是否分批补跑。只有在“结果尚未持久化、全部只存在内存里”这一种情况下,才需要优先抢救进程而不是保护快照——因为此时一旦退出,已有结果会随进程一起消失。
同样是被限流,结果的安全性取决于写入时机,而不是取决于报错信息本身。可以把脚本分成两类来对待。
判断方法很直接:看代码里写文件的语句在循环内还是循环外。循环内写入的,属于第一类;循环外写入的,属于第二类。这个区别决定了下一步该保什么。
确认结果已经落盘后,按顺序做三件事,而不是马上改小并发继续跑。
result_20240612_batch1.csv。后续补跑写入新文件,不覆盖这一份。做完这三步,再决定补跑策略。如果断点清晰、失败条目可枚举,就按断点分批续跑;如果断点混乱、日志缺失,宁可放弃这批未完成部分,用快照里的完整结果先交付,剩余条目另起一批。
反例出现在结果尚未持久化的时候。假设脚本把几百条查询结果攒在内存里,准备全部完成后统一写盘,此时中途被限流。若照搬上面的做法先去复制文件,会发现文件根本不存在或只有上一次的旧版本,真正的结果还在进程内存中。这种情况下正确的动作是:先让脚本把内存中已获得的部分结果强制写出(哪怕写成一个不完整文件),再退出。判断依据是——结果是否存在磁盘上,而不是是否存在过。
另一个会让结论失效的条件是:结果虽然落盘,但写入过程本身不完整,比如文件写到一半被中断,留下半行记录。此时直接拿这份文件做后续分析会引入脏数据,需要先校验行数和字段完整性,再决定是否作为快照保留。
限流可能是短时的,也可能是配额已经用尽。两者处理方式不同:短时限流等待一段时间后小批量重试即可;配额用尽则要等到下一个周期,继续调用只会持续被拒。区分办法是看返回信息里是否带有重置时间或剩余额度提示,具体字段因工具而异,需要以实际返回内容为准。
在无法确认性质时,可以用一个保守动作试探:只发一条查询,观察是否成功。成功则说明限流已缓解,可以按断点小步续跑;仍然失败则停止,把快照作为本批交付物,等下一个周期再补。这个动作的成本很低,但能避免在配额耗尽时反复无效调用、把日志刷满。
与其在限流发生后补救,不如把写入时机前移。把“循环外统一写”改成“循环内逐条追加”,限流带来的最大损失就从整批变成一条。同时给每条记录加上状态字段,标记成功、无结果、被限流三类,补跑时只挑被限流的条目。这样即使中途被打断,已有结果始终可用,补跑范围也始终可控。
需要核对的仍然是工具本身的返回结构和配额规则,不同工具对限流的表述和重置机制并不一致,具体信息以实际接口返回和账户额度说明为准,不要凭印象假设。下一步动作很明确:打开脚本,确认写文件语句的位置,然后决定是冻结快照后补跑,还是先抢救内存结果。