摘要

  • RFC 2373 从单播地址空间分配 anycast,地址位本身不会宣布它由多个接口共享,也不会指出路由最终选中了谁。
  • “最近”指路由协议按当时距离度量选出的结果,不等于地理最近、时延最低、最健康、负载最轻或始终同一台机器。

相同的地址,没有内置的赢家

RFC 2373 从接口定义 IPv6 地址。单播指向一个接口,多播指向一组接口并向全部交付,anycast 也指向一组接口,却只交付给其中“最近”的一个。

关键不在于新增了什么字段,而在于没有新增字段。Anycast 直接取自单播地址空间,沿用单播格式,在语法上与单播无法区分。同一串单播形式的地址被配置到多个接口后,参与节点还必须显式知道它是 anycast。

因此日志里的一串地址回答不了最诱人的问题:它没有说明背后是一个接口还是一个集合,没有命名会应答的成员,也没有保存路由为什么选择它的证据。

“最近”属于路由,不属于地址

规范给“最近”加引号是有原因的。距离由正在运行的路由协议衡量,其中已经包含拓扑、策略和当时的通告。它不是地理距离,不是应用时延,也不是负载、进程健康或所有权的表达。

这种设计不必发明新的报文字段,普通转发就能把流量引到一个成员。但成员也可能随路由变化而改变。两个观察点使用同一目的地址,可以抵达不同接口;同一观察点在稍后也可能换一个接口。稳定的字符串是会合入口,不是稳定机器名。

成员关系藏在路由里

RFC 2373 为每个 anycast 集合定义一个最长前缀 P,用它圈定所有成员所在的拓扑区域。在 P 内部,每个成员必须以单独的主机路由出现;在 P 外部,anycast 地址可以聚合进 P 的通告。

这也暴露了规模代价。若成员之间没有共同的拓扑区域,P 可能退化为空前缀,独立路由就要传播到整个互联网。规范把它称为严重限制,并预计全球 anycast 集合只能受到严格约束。

地址位并不携带这份成员台账。运营者通过接口配置和路由通告创造集合,而聚合又会有意让远端看不到单个成员。

全零接口标识也可能表示“任意一台路由器”

强制支持的 Subnet-Router anycast 把歧义变得具体:子网前缀后接全零接口标识。从语法上看,它和接口编号为零的单播地址相同;从运行规则看,该子网上所有路由器都要识别它,报文只交给其中一台。

规范还要求实现默认把其他地址当作单播,除非显式配置为 anycast。地址分类的一部分现实因此存在于 128 位之外。配置和转发状态可以赋予相同写法不同的交付含义。

早期限制记录的是尚未解决的不确定性

RFC 2373 坦言,人们对互联网范围内任意使用 anycast 的经验很少,也已知存在复杂性和风险。它暂时禁止 anycast 作为源地址,并把分配对象限制为路由器。后来的 IPv6 地址架构取消了这些早期限制,却保留了同样的语法与路由选择核心。

历史不能被压平。1998 年的做法体现了最小初始规范:复用熟悉的地址和路由机制,先规定路由器场景,并在经验不足时收紧未知表面。后来的放宽不能倒过来证明早期问题已经解决,更不能证明某种现代服务当时已经部署。

一次响应最多证明:在某个时刻,从某个观察点,某条路径抵达了某个应答成员。它不能列出完整成员集,不能证明路径最优或由健康检查选中,不能保证下一包仍到同一实例,也不能证明应用已经完成。

可靠的证据链应分开记录目的地址、配置成员、每条路由通告、观察点所选路径、收到报文的接口、应答进程、会话状态与最终业务结果。

按照 Lu Heng 的“运行代码优先”,权威在真正生效的配置和转发里,而不在地址标签里。“最小初始规范”解释了为什么 IPv6 没有制造一种自描述的 anycast 类型。“现实层次”则要求把地址、路由、响应和完成的服务动作作为相邻但不同的事实。

RFC 2373 让一个地址能够找到集合中的一个成员。它的成功,恰恰来自没有假装地址提前知道那会是哪一个成员。