外链检查工具脚本调用遇到限流时怎样保护已有结果

📍 WDQWDWQD987AAAAA:216.73.216.137
📱 Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko; compatible; ClaudeBot/1.0; +claudebot@anthropic.com)
🔗 /b3b64041ff62.html
📄

外链检查工具脚本调用遇到限流时怎样保护已有结果

结论先行:如果限流发生在分页或分批抓取的中途,保护已有结果的关键不是“继续重试到成功”,而是把已返回的数据落盘成可校验的分片,并让重试从最后一个完整分片之后继续。只有当你能确定被截断的那一批数据没有被写入、且下一批的起始游标仍然有效时,继续重试才是安全的;否则重试会把缺口掩盖成“看起来完整”的结果。

先分清限流截断的是哪一层

脚本调用外链检查工具时,限流可能发生在三个不同层面,对应三种不同的保护动作。

判断属于哪一层,靠的是响应元数据而不是感觉:HTTP 状态码、响应体的长度是否与声明的长度一致、分页字段是否仍然返回同一个起始位置。把这些字段记进日志,比事后猜原因可靠得多。

把结果写成带校验的分片,而不是一路追加

很多人写脚本时用追加模式,一条一条往同一个文件里写。限流中断后,这个文件既不知道写到哪,也无法判断中间有没有缺行。改成按批落盘的分片结构,情况会好很多。

假设每批抓取 100 条外链记录,那么每批写成一个独立文件,文件名带上批次序号和该批的起始游标,例如 batch_0007_start_abc123.json。文件内部记录该批的条数、首尾记录标识和写入时间。这样做的直接结果是:中断后你只需要检查最后几个分片,就能确定最后一个完整批次在哪里,重试起点也就有了明确依据。

配合一个清单文件记录“哪些批次已完成、哪些批次待重试”,可以把恢复逻辑从“猜”变成“查”。清单本身要最后写入,避免出现分片已写但清单未更新的中间状态。

重试前先做一次缺口核对

限流恢复后不要立刻从头跑。先做三步核对,再决定下一步动作。

  1. 按批次序号排序,检查是否存在序号跳跃。序号跳跃说明有批次根本没写成功。
  2. 对相邻批次做首尾标识衔接检查:上一批的最后一条记录标识,是否等于下一批第一条记录的前驱。不衔接就说明中间有缺口。
  3. 对每个分片重新计算条数,与清单中记录的条数比对。不一致的分片一律标记为可疑,不参与后续合并。

这一步的产出是一份“可信批次列表”。后续只重试不在列表里的批次,而不是重跑全部。这样既省调用次数,也避免重复数据污染最终结果。

什么情况下“继续重试”反而是错的

前面说的方法有一个明确的反例:当工具的分页基于一个会随会话变化的游标,而限流又恰好重置了会话时,旧游标可能指向一个语义已经不同的位置。此时按旧游标继续重试,拿回来的数据可能既不重复也不缺失,而是错位——它属于另一个时间点的结果集。

识别这种反例的证据是:重试返回的第一条记录标识,与中断前预期的下一条不一致,但接口没有报错。一旦出现这种情况,正确的动作是放弃当前游标,从该批次之前的最后一个可信锚点重新开始,并把这次事件记录为“游标语义变更”,而不是当成普通限流。

如果无法确定游标是否会随会话变化,保守做法是把每个批次的起始游标也写进分片,恢复时优先使用分片内记录的游标,而不是脚本内存里的游标。

给下一步的恢复动作定一个可执行顺序

综合下来,限流后的恢复顺序可以固定为:读取清单,确定最后一个完整批次;对后续分片做缺口核对,标记可疑分片;用分片内记录的游标而非内存游标发起重试;重试成功后先更新清单,再继续下一批。每一步的结果都会影响下一步:如果缺口核对发现游标语义变更,就不能按普通重试处理,而要退回锚点;如果重试再次被限流,则延长退避并保持分片不变,等待下一次核对。

这套顺序的价值在于,它把“限流”从一个需要临场判断的异常,变成一个有固定分支的流程。只要分片和清单是可信的,限流本身不会损坏已经拿到的结果,真正需要防的是重试时把缺口写成了完整。

图1 图2

nginx