3251 字
约 10 分钟
15
S02-A11 · 网关的两种职责:路由收敛与策略执行放在一起

网关最初只做一件事:把请求送到正确的后端。后来它上面长出了鉴权、限流、灰度、埋点、风控、协议转换。没有哪一次是"决定"加上去的,都是顺手加上去的——顺手的原因是它离数据最近:请求先到网关,在网关加一段匹配规则就能拿到全量请求上下文,而在业务侧做同样的事要改 N 个服务、发 N 次版。

于是两种完全不同节律的职责共用了一套机制。路由要的是稳定与低延迟,策略要的是可变与可审计;两者的变更频率差一个数量级,评审强度、回滚路径、失败形态全不一样。共用一个机制之后,被牺牲的一定是策略那一侧——路由坏了会响,策略变粗不会响。


1. 两种职责的判据不同,变更频率差一个数量级

维度 路由收敛 策略执行
目标 请求到达正确的后端 请求被正确地允许 / 拒绝 / 染色
正确性判据 无环路、无黑洞、拓扑与注册中心一致 与策略声明一致,且每条生效可解释
变更频率(典型量级) 每次扩缩容与发布,月级;实例稳定时更低 每次活动与风控调整,天级到小时级
谁能改 平台 / 运维 风控 / 增长 / 业务
回滚代价 秒级,改回一张路由表 取决于策略耦合面,常需重新走发布
失败形态 硬错误:502 / 504,立刻可见 软错误:误拒、漏放、按粗粒度生效
天然时间尺度 分钟到小时(拓扑收敛窗口) 秒到分钟(活动节奏)
最小验证单位 一次连通性探测 一次规则命中样本回放

两段配置常常在同一个文件里,这是问题的起点:

// 同一份网关配置,两段却属于两条完全不同的评审路径
routes:
  - id: order-v2
    match: "/api/order/**"
    upstream: order-svc:8080        // 由发布流程驱动,变更要等拓扑
policies:
  - id: auth-jwt
    match: "/api/**"
    action: verify                  // 变更由风控驱动,节奏以小时计
  - id: gray-order
    match: "/api/order/**"
    weight: 5                       // 变更由增长驱动,跟活动节奏走

同文件意味着同一次发布、同一条审批链、同一个故障域、同一个回滚动作——机制共用,目的不共用,这就是"两个目的共用一套机制"的原型。


2. 共用之后的三个后果,以及下移能换到什么

后果 机理 早期信号 代价落在谁身上
策略变更引发全站风险 策略匹配面覆盖所有路由,一条规则的默认动作写错就作用于全站 网关 CPU 与延迟随规则条数缓慢抬升 与这次策略无关的业务
路由变更要过策略审批 审批粒度按文件而不是按段落,两者的风险等级被合并成最高 发布周期被拉长,紧急回滚也要等人 发版速度与故障恢复速度
故障域合并 一台网关同时承载两种失效模式,且互相放大 网关错误率与单业务错误率失去相关性 全站

第二条最隐蔽:它不产生故障,只产生等待,而等待不出现在任何告警面板上。

"网关是唯一入口"的好处与代价同样明确:

  • 得到:凭证校验只写一次、观测点唯一、入口限流可统一、客户端不用知道服务拓扑。
  • 付出:共享故障域(爆炸半径 = 全站)、上游能力上限变成所有业务的延迟下限、任何策略缺陷都是全站级而不是单服务级。

把策略下移是常见解法,但它是交换,不是净化:

下移位置 换到什么 换掉什么
Sidecar / 服务网格 策略随服务版本发布,爆炸半径收敛到单服务 失去单一审计面;每个实例都要资源与运维成本
客户端 SDK 无额外进程,链路延迟最低 语言绑定、升级要重发,多语言必然版本不一致
服务内部 判据可读业务状态,最精确 每个服务重复实现,规则逐渐漂移
留在网关 单点修改、单点审计、单点回滚 变更频率错配(见第 3 节)

该放哪,用四条判据过滤:

// 策略留在网关需要同时满足以下四条
// 1. 判据只依赖请求本身:路径、header、IP、token 声明
// 2. 不依赖业务状态:用户等级、订单状态、库存、风控名单
// 3. 策略变更不需要与业务代码同版本发布
// 4. 失败语义可以统一:拒绝 / 放行 / 降级都不需要业务侧解释
// 反例:按"用户是否首单"做灰度 → 判据在业务库 → 放网关等于让入口反向依赖业务数据

灰度与限流同理:按 header 与比例的灰度可以留在网关;按业务状态分流的灰度要反向查库——一旦查库,网关就从无状态转发变成有状态依赖,爆炸半径扩大一个量级。


3. 为什么牺牲不会被发现

被牺牲的是策略执行的可变性——策略被迫变慢、变少、变粗。它不被发现,因为三件事同时成立:

  1. 策略的失效没有硬阈值。"灰度只按请求头,不按用户属性"不会报错,只会让灰度效果打折;"风控只能上粗规则"不会报错,只会让拦截率略低。打折与略低都不触发任何告警。
  2. 延迟的增长是毫秒级的。规则从 10 条涨到 200 条,单请求额外延迟按毫秒计,混在正常的 P99 抖动里看不出来。按版本核对时,注意区分"网关自身耗时"与"网关上游耗时"两个口径,否则永远定位不到。
  3. 审批的代价记在别人账上。策略改得慢,痛的是业务而非平台,而平台看到的指标是健康的。

根因一句话:高频变更的东西,不该放在最低频的路径上。

// 变更频率(典型量级,用自己仓库的发布记录核对)
// 路由与拓扑变更   :月级
// 上游实例增删     :天级,随扩缩容
// 鉴权 / 限流策略  :天级到小时级
// 灰度规则         :跟业务发版节奏,最频繁
// 埋在同一个热路径上的机制,其变更成本由其中最慢的流程决定
// → 高频变更被迫排队等待低频流程的窗口,且不会有人报错

配置化的策略比代码化的策略更难测,这一点必须提前认清:配置不过类型检查、不进单测、可以线上直接改,回滚动作常常是"再改一次配置"而不是"回退一个版本"。因此它的实际评审强度往往低于同等风险的代码改动。评审标准应当按改动类型分开定:

改动类型 评审重点 必须可回滚的时限
路由 拓扑正确性、超时与重试是否继承下游设置 分钟级
策略 生效范围、默认动作(放行还是拒绝)、能否单独撤回 秒级
业务逻辑 不属于该层,退回服务侧 —(根本不该出现)

四个口径能把"是否正在牺牲策略"变成可观测的事实:

// 缺任何一个口径,都无法判断牺牲是否已经发生
gateway_policy_change_total        // 策略变更频率,按周聚合看趋势
gateway_fault_ratio                // 网关相关故障数 / 总故障数
gateway_added_latency_p99          // 网关总耗时 - 上游耗时,只看差值
gateway_policy_rollback_duration   // 从发现到策略失效的耗时
// 判据:策略变更频率连续下降,同时网关故障占比上升 → 职责合并的代价已经落地

"网关不做业务"这条界限反复被突破,原因很现实:它离数据最近。请求先到网关,全量上下文都在手里,写起来最省事;而且在网关写一次,等于省掉 N 个服务的重复实现——短期收益立刻可见,长期代价(变更频率错配、共享故障域)要半年后才以"发版慢""灰度不灵"的形式浮现。这就是权衡被系统性做反的机制。


4. 排错

现象 可能原因 验证方式 处置方向
网关延迟缓慢上升,无发布 策略规则条数堆积,匹配变成线性扫描 对比网关自身耗时与上游耗时 拆分策略层,或把纯 header 无关的规则下沉
策略改动偶发不生效 匹配顺序与默认动作不明,两条规则互相遮蔽 用一条样本请求回放所有命中规则 规则要能列出"哪条最终生效"
回滚路由反而引发策略报错 两段共用同一份配置,回滚带回旧策略 对比回滚前后的策略列表差异 两段分文件、分发布通道
网关故障时全站同时故障 故障域合并,单业务降级救不了入口 看网关错误率与单业务错误率的相关性 入口分级:静态与只读链路走独立通道
无人能回答某条策略为什么在 配置长期叠加,缺少归属与到期时间 逐条策略追责任人 策略必须有 owner 与有效期

5. 边界

场景 结论 理由
只有两三个服务 全部放在网关 共享故障域的代价小于多套机制的一致性问题
策略几乎不变(一年几次) 可以共用 变更频率错配的前提不成立
团队无独立运维能力 先集中再拆分 拆开后的每份策略都要有人维护,无人维护等于没有策略
判据纯请求头、无业务状态 适合留在网关 无状态转发,爆炸半径可控
需要按业务状态做灰度 下移 网关一旦查业务数据,就失去了它最大的价值
入口既要鉴权又要协议转换 分层而不是合并 鉴权与转换的失败语义、回滚单位都不同
// 拆分的最小动作:把"变的东西"和"不变的东西"分到两条通道
// 通道 A(月中变更一次):路由、超时、重试继承、上游地址
// 通道 B(日级变更):鉴权规则、限流阈值、灰度比例、埋点开关
// 验收:改一条灰度规则不触发路由校验;回滚一条策略不发版

6. 自测

  1. 路由与策略这两类改动的变更频率差多少?这个差值为什么决定了它们不该共用同一条发布通道?
  2. 三节里说的"被牺牲的是哪一个目的"?为什么它的失效不会被任何告警捕捉到?
  3. 灰度放在网关还是放在服务的判据是什么?一旦需要查业务数据,代价具体是什么?
  4. 为什么"网关不做业务"这条界限会被反复突破?短期收益与长期代价各是什么?
  5. 配置化策略为什么比代码化策略更难测?这应该怎样改变它的评审标准?
  6. 如果只保留一个度量来证明"职责合并已经在付出代价",你会选哪一个,判据是什么?
S02-A11 · 网关的两种职责:路由收敛与策略执行放在一起
https://www.clxhxhhr.top/posts/6364/
作者
clxstart
发布于
2024-12-31
许可协议
CC BY-NC-SA 4.0
评论
0 条
还没有评论,先写一条吧。