← 路由设计 · 稳定入口与可变目标 / 为什么要有路由这一层 · indirection 的力量 待审核 1 / 23

为什么要有路由这一层 · indirection 的力量

计算机里有句老话:任何问题都能靠加一层 indirection(间接)解决。路由就是这句话在「地址」上的体现——与其让每个使用方直接硬编码最终地址,不如对外只给一个稳定的入口,入口背后真正去哪由你集中决定。一旦解耦,「改目标」就和「改入口」分了家:目标随便换,入口纹丝不动。而这一层本身又能拆成两半:一张规则表决定「这个入口该去哪」(rule),再用某种机制把请求真正送过去dispatch)——本系列各页讲的,都是这两半的不同组合(匹配引擎是纯粹的 rule;HTTP 重定向分享入口deep link 各落地一种 dispatch)。

下面这条短链 vega.link/promo 被印进海报二维码、塞进短信、嵌在 App、买在广告位。试着改一次目标,看四处嵌入点同时跟着变——而那些已经印出去、发出去的链接一个字都不用动

这一层换来了三件事。 统一改址:改一处配置,所有渠道、所有已发出的链接同时换目标——海报不用重印、短信不用重发。集中统计:因为所有流量都过同一个入口,你才能在这里记下「谁来的(?from=)、来了多少」,这是各渠道各自硬编码目标时拿不到的来源数据。安全下线:活动结束,把目标指向一个「已下线」页即可,而不是留一地指向 404 的死链。

1 · 把这一层拆开:rule + dispatch

上面那个 demo 看着只是「改目标 / 看入口跟随」,但它内部一定做了两件正交的事:先查规则决定这个入口此刻该去哪(rule),再把请求送过去(dispatch)。rule 这一半是全系列共用的「决策」——匹配引擎页把它单独讲透(路由表自上而下匹配、提取 params、顺序即优先级)。而 dispatch 这一半,「送过去」其实有好几种互不相同的机制,本系列其余几页各落地一种——不要把它笼统当成「proxy」,proxy 只是其中最具体的一种:

dispatch 机制 谁去请求目标 客户端看得见目标? 本系列对应页
reverse proxy 服务端代取目标内容、原样回传 看不见,地址栏不变 分享入口/api/* 反代
redirect (3xx) 客户端收到 Location自己再请求一次 看得见,地址栏变成目标 HTTP 重定向 · 短链 · /s/:code
rewrite 服务端内部把 path 改写,再处理 看不见,地址栏不变 分享入口* fallback → index.html
OS-level 路由 操作系统按规则分发(进 App 还是开网页) ——,没有地址栏 deep link / Universal Link

四种 dispatch 都搭配同一半 rule(决定去哪)。「indirection」是这把伞:proxy / redirect / rewrite / OS 路由,乃至 DNS / CDN / 符号链接,都是「稳定名字 ↔ 可变目标」的同一招、不同的送达方式。

##「直接硬编码」vs「过一层入口」

维度 各处直接写死最终地址 统一过一个路由入口
改目标 逐处去改、已印出的改不了 ✗ 改一处配置,全部跟随 ✓
统计 各渠道分散、口径不一 ✗ 入口处统一统计(渠道 / utm)✓
灰度 / AB 做不了 ✗ 入口处按比例分流到不同目标 ✓
下线 变一堆死链 ✗ 统一指向「已结束」页 ✓
代价 无(但债留给未来) 多一跳 + 一套路由配置要维护

这正是短链服务(bit.ly)、广告 tracking link、App 的 deep link 中转,乃至 DNS CNAME 共同的设计动机——都是「稳定名字 ↔ 可变目标」的同一招。

它无处不在。 你已经在用很多「indirection 层」而不自知:DNS 把域名指向可变的 IP、CDN 把同一 URL 指向最近的边缘节点、符号链接把路径指向可变的文件、API gateway/v1/* 指向后端可替换的服务。它们解决的是同一个问题:让使用方记住一个不变的名字,而把「它到底指向谁」留给你随时调整。 本系列后面几页就是这一招在 HTTP 重定向、分享入口、App deep link 上的具体落地。

2 · 相关页