把参数组合当作无限集合去枚举,永远做不完。可行做法是反过来定义“有效地址集合”:先确定哪些参数组合值得生成地址,再让注册服务只接受落在该集合内的参数。对已有经验的读者,关键遗漏条件通常是:只校验了单个参数,没有校验参数之间的组合关系。下面以一个资料表或页面为对象,给出可执行的处理顺序。
如果同一个逻辑地址能写出多种参数顺序、大小写或默认值形式,集合就永远无法闭合。先规定规范化规则:参数按固定顺序排列,键名统一大小写,默认值不写入地址,空值与缺省视为同一种情况。规范化之后,两个不同写法如果折叠成同一串,它们就属于同一个地址,集合规模才可计算。
这一步的实际动作是:从现有资料中抽一批地址,按上述规则重写,观察折叠后还剩多少条。如果折叠比例很高,说明此前的“无限增长”有相当部分只是写法重复,而不是真实组合爆炸。这个结果直接决定下一步是收紧参数定义,还是继续处理组合关系。
只给每个参数单独列合法值,组合数仍是各参数取值数量的乘积。有效集合需要的是约束,而不是清单。常见的约束形式有三类:互斥(两个参数不能同时出现)、依赖(出现A必须同时出现B)、取值范围联动(B的取值上限由A决定)。
把这些约束写成可执行的校验规则后,无效组合会在生成阶段就被排除,而不是等到注册或入库时才报错。假设某地址有三个参数,分别有10、10、10种取值,单独白名单下理论组合是1000;如果规定其中两个参数互斥、第三个参数只在特定取值下出现,实际有效组合可能降到几十。这里的数字仅用于说明约束对集合规模的影响方式,不是任何真实统计。
定义好的集合必须有一个执行位置,否则只是文档。通常有两个选择,成立条件不同:
两者可以同时存在,但需要指定哪一侧是权威判定。如果两侧规则不一致,就会出现“生成侧认为有效、接入侧拒绝”的地址,排查时容易被误判为服务异常。
参数组合不在有效集合内,和组合有效但当前无法处理,是两种不同原因,处理方式也不同。前者应返回明确的参数错误并指出违反的约束;后者应返回可重试的状态。如果两者混用同一个错误码,调用方无法判断该改参数还是该等待。
一个可区分的证据是:把同一组参数原样重试。如果结果稳定失败,多半是集合判定问题;如果时好时坏,则更可能是资源或限流问题。这个判断会影响下一步动作——前者去修约束规则,后者去查处理容量。
以读者手中的一份参数资料表为对象,可以按以下顺序推进,每一步的结果决定下一步:
如果第4步折叠后数量仍然很大且无法收敛,说明还有参数没有被约束住,应回到第3步补充约束,而不是继续扩大生成范围。需要提醒的是,站点地图或抓取限制这类手段都不保证地址被收录或移除,它们不能替代对有效集合本身的定义。
当有效集合被明确定义并落到一个执行位置后,参数组合的增长就从“无限枚举”变成“按约束判定”,后续的异常排查也才有稳定的参照点。