中断后不要从“扫到哪一行”推算覆盖范围,而应先确认工具在中断前是否已经把每个对象的处理状态写入可持久读取的记录。若记录里只有进度百分比或已处理数量,覆盖范围通常无法可靠还原;若记录里保留了对象标识和逐项状态,则可以据此重建已覆盖集合,再决定重扫全部还是只补未完成部分。
全站扫描被中断后,最常见的矛盾是界面曾显示接近完成的进度,但恢复后可用结果明显偏少。这并不一定说明工具丢数据,也不一定说明扫描其实没跑多少。两种解释都成立,需要分开验证。
解释一:进度按“已发现对象”计算,而不是按“已完成处理”计算。扫描前期先遍历站点结构,把大量链接或文章加入队列,进度因此快速上升;真正耗时的抓取、解析、状态判断才刚开始,中断时完成比例远低于进度数字。
解释二:进度按“已完成处理”计算,但完成记录只保存在内存或临时会话中。中断使这部分状态丢失,恢复后只能从最后一个持久化检查点继续,于是已覆盖范围退回到检查点位置,看起来像白跑了一段。
这两种解释对应的补救动作完全不同:前者需要重新界定“发现”和“完成”两个口径,后者需要先确认检查点机制是否存在以及写入频率。
不要依赖进度条、日志末尾时间或已处理计数来判断覆盖范围,这些信息都可能是聚合值。优先找对象级记录,即每个待处理对象都有一条可核对的条目,包含稳定标识和状态字段。
可用的证据通常具备这些特征:
如果记录满足以上条件,可以按对象标识做集合运算:把全站对象清单作为全集,把状态为“已完成”的条目作为已覆盖集合,两者之差就是待补集合。这个动作的结果直接决定下一步——差集很小就只补差集,差集接近全集或状态字段不可信就安排完整重扫。
如果工具只留下聚合进度,没有逐项状态,就不要假装能精确还原覆盖范围。此时可行的做法是估计一个保守边界,并明确它是估计而不是事实。
假设一次扫描共发现约一千个对象,中断时进度显示百分之八十,但无法确认这百分之八十指发现还是完成。可以从中抽取若干对象,逐个检查它们是否在结果中、结果是否完整、是否带有处理时间。若抽样中大量对象只有发现记录没有处理结果,就应按“完成比例远低于进度值”处理,把补扫范围放大;若抽样对象普遍有完整结果,才可以把未覆盖范围收敛到尾部区间。
抽样的价值在于暴露口径,而不是给出精确比例。样本要覆盖不同目录深度、不同内容类型和不同发现顺序的位置,只抽首页附近的对象会系统性高估覆盖率。
一个可执行的动作顺序是:先冻结当前记录,导出对象级状态;再生成全站对象清单;然后计算已完成、失败、缺失三类集合;最后根据缺失集合的规模和分布选择补扫或重扫。
这个动作的结果会改变后续判断。如果缺失对象集中在扫描尾部,说明中断点之后的队列没有执行,补扫尾部即可;如果缺失对象随机散布在各个位置,说明持久化或状态写入本身有问题,补扫仍会重复丢失,应先修复记录机制再重扫。若已完成集合中存在大量“成功但内容为空”的条目,那属于处理质量问题,不是覆盖范围问题,需要单独处理。
第一,把请求量归零当作扫描完成的证据。请求停止可能来自中断、限流、超时或主动暂停,不能单独证明对象已处理完。
第二,把日志无报错当作全部覆盖。日志级别、缓冲写入和异常吞掉都会让错误不可见,必须回到对象级状态核对。
第三,用“重新扫一遍最保险”代替判断。重扫确实能覆盖全集,但会消耗时间、触发限流,还可能覆盖掉中断前有价值的失败记录。只有在状态记录不可信或缺失分布无法解释时,重扫才是合理选择。
具体工具是否提供对象级状态导出、检查点恢复或差集补扫,需要按你实际使用的版本核对,不能假定某个按钮或入口一定存在。判断覆盖范围的依据始终是可核对的对象清单与状态记录,而不是界面上那个中断前留下的进度数字。