灰度只放出一小部分URL,能提前看到抓取与收录反应,却也会把“样本内成立”误判成“全量都成立”。真正要防的例外,往往藏在灰度没覆盖的模板分支、参数组合和站点层级里。更稳的做法不是扩大灰度比例,而是先按URL模式分层,把每个分支都纳入样本,再决定是否全量发布。
灰度发布通常按流量比例或目录前缀随机抽取URL。随机抽样的前提是:被抽中的页面与未抽中的页面在结构上同质。但站点里常存在少数分支,它们的模板、渲染方式或链接深度与主样本不同。例如主列表页是服务端渲染,某个筛选参数触发的页面却依赖客户端脚本填充正文。灰度若只覆盖前者,全量发布后后者就会成为例外。
判断差异来源,可以对比灰度样本与全量URL集合的三个维度:模板标识、是否依赖JavaScript渲染、以及从首页到该页的最短点击距离。三者中任一维度在两组间分布明显不同,就说明灰度样本不能代表全量。
把待发布页面按可识别的模式分组,而不是按数量平均分配。分组依据可以是路径结构、查询参数的有无、以及页面类型标签。每组至少放一个URL进灰度,组内页面结构一致时,一个样本就能代表该组。
这样做的代价是灰度覆盖的URL数量变多,发布节奏变慢。收益是:当某组出现抓取异常时,你能定位到具体模式,而不是面对一堆混杂数据无从判断。
灰度期结束后,不要只看“收录了多少”。更有区分度的证据是:同一组内,被抓取URL的响应状态、正文可见文本长度、以及页面标题是否与预期一致。如果某组在灰度中全部正常,全量后该组出现大量“已抓取但未收录”,先检查该组的正文是否在无脚本环境下为空。
另一种常见例外是参数页面。灰度时只测了无参数版本,全量后带参数的URL被大量链接暴露。此时可对比:同一路径下,带参数与不带参数的页面,其规范化标签是否指向同一地址。若不一致,参数页面可能被视为独立页面,稀释了主页面信号。
假设一个短例子:某站点有1000个产品页,其中950个走标准模板,50个走定制模板。灰度按10%随机抽取,抽中95个标准页和5个定制页。标准页全部正常,定制页中有2个因缺少服务端渲染而未被收录。若只看“灰度收录率98%”就全量发布,剩余45个定制页会全部暴露问题。正确动作是:把定制模板组单独标记,先修复渲染,再重新灰度该组。
灰度结论能否外推到全量,取决于三个条件是否成立:样本覆盖了所有模板分支;每个分支的URL在灰度期被至少抓取一次;抓取时的响应与全量发布后一致。任一条件不成立,灰度就只能作为参考,不能作为放行依据。
如果站点使用站点地图提交URL,注意站点地图只帮助发现,不保证收录。灰度中站点地图里的URL被抓取,不等于全量后同样会被抓取。抓取预算和优先级会随URL总量变化,灰度期的小规模抓取表现不能直接线性放大。
另外,robots.txt限制抓取不等于可靠的索引移除。灰度中若用robots.txt挡住某组URL,这些URL仍可能因外部链接被索引。要确认例外是否真实,应查看该URL在搜索结果中的实际状态,而不是只看抓取日志。
把上述判断落到一个具体页面对象上,可以按以下顺序操作:
这个流程的代价是发布周期变长,尤其当模板分支多时。但它把“全量后才发现例外”的风险,提前到了可控的小范围内。下一步动作取决于灰度数据:若所有组都通过,全量发布;若某组未通过,只修复并重测该组,不扩大灰度比例。这样,灰度才真正起到暴露例外的作用,而不是制造“一切正常”的假象。