灰度阶段只放少量流量,最容易暴露的不是跳转本身失效,而是全量发布时才会触发的例外分支。常见情形是:灰度样本恰好绕开了某个条件,比如特定语言、登录态、移动端 UA、带查询参数的旧链接或某个子目录,而全量后这些请求大量出现,被另一条更靠前的规则先匹配走。此时你要决定的是保留现有规则、改写匹配顺序,还是退出这次发布。
灰度只放 1% 流量时,命中样本是随机的,但随机不等于均匀。如果这 1% 恰好落在默认分支上,你看到的“正常”只是默认分支正常。判断例外来源,可以按下面这组可区分证据来分:
这四类证据指向的动作不同。前两类靠调整规则顺序或匹配精度就能解决;第三类要先看分流层,改跳转规则可能完全无效;第四类则要回到目标页确认它是否真的存在且内容对应。
保留适用于例外范围明确且可控。比如例外只影响一个已知子目录,且该子目录本就不需要跳转,你可以在规则里显式排除它,然后继续灰度。前提是你已经能列出例外的完整清单,而不是“大概就这些”。
改写适用于例外由规则顺序引起。把更具体的规则放到更宽的规则之前,通常能让灰度与全量行为一致。前提是你能在灰度环境复现该例外——如果复现不了,改写就是盲调,全量后可能引入新的例外。
退出适用于例外无法在发布前穷举,且影响面涉及关键路径,比如结算、登录或主要入口页。此时回退到发布前状态,比带着未知例外全量更稳。前提是回退本身不会造成新的状态不一致,例如已经发出的跳转缓存需要一并考虑。
三种选择不要求同时成立。多数情况下只有一种前提真正满足,选它即可。
假设旧站有一批形如 /old?ref=xxx 的链接需要跳到新地址。灰度时你只测了不带参数的 /old,它正确跳到目标页。全量后带参数的请求出现,而规则里有一条更宽的匹配先接住了它们,把请求导向了首页。结果不是跳转失败,而是跳到了错误目标。
这个例子里,动作是“在灰度中补测带参数的变体”。如果补测后仍跳错,说明匹配顺序需要改写;如果补测后正常,说明之前的灰度样本不具代表性,应扩大样本再判断,而不是直接全量。这个动作的结果直接决定下一步是改规则还是改测试方法。
小流量灰度能验证跳转是否可达、状态码是否正确,但它无法证明所有条件分支都被覆盖。全量前的关键动作,是把灰度中未出现的请求类型单独列出来,至少覆盖带参数、带语言前缀、登录态和移动端这几类。如果这些类型无法在灰度中构造,就应把它们当作已知未知项处理,而不是默认它们会正常。
另外,抓取量或请求量在灰度期间归零,不能单独证明跳转处理正确。它也可能是灰度比例过低、样本被缓存命中,或该路径本就没有外部入口。要区分这些解释,需要结合日志中实际命中的规则分支来看,而不是只看总量。
无论选择保留、改写还是退出,都应先固定一条可回退的边界:记录当前生效的规则版本、灰度比例和已观察到的例外类型。这样当全量后出现新例外时,你能判断它是改写引入的,还是原本就存在只是未被灰度覆盖。没有这条边界,后续每一次调整都会变成无法归因的叠加。
如果最终选择改写,改完后应重新走一遍小流量灰度,并刻意构造之前遗漏的请求类型;如果选择退出,回退后要确认旧规则是否仍能正确处理灰度期间已经跳转过的请求,避免出现同一链接前后指向不同目标的情况。