ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

ax调度深度解析:Anycast原理、BGP选路与上线避坑指南

ax调度深度解析:Anycast原理、BGP选路与上线避坑指南 最近又有朋友拿着一张 ping 截图来问我同一个域名从上海、广州、洛杉矶三个地方 ping 出去解析出来的 IP 竟然不一样而且每个地方访问都很快这算不算“负载均衡”其实这背后藏着一套非常经典的网络调度机制——ax 调度。在广域网和 CDN 场景里大家习惯把 Anycast 调度简称为 ax 调度它解决的核心问题就是“让每个用户都找到离自己最近的节点”。这篇文章我想把 ax 调度这件事讲透它为什么能起作用、调度粒度到底在哪里、上线时容易踩什么坑、以及哪些业务其实根本不适合上 Anycast。内容会偏网络工程和站点架构一点但我会尽量用大白话把关键逻辑讲清楚适合正在做 CDN、递归 DNS、对象存储入口或者准备把业务从单地域变成多地域接入的读者参考。1. 一条 ping 记录背后的调度逻辑ax 调度到底在干什么1.1 互联网寻址的一个默认假设正在被打破我们大多数人学网络的第一课就是IP 地址标识一台主机数据包按目的 IP 寻路。这个模型在很长一段时间里是对的但它有个前提——一台服务器只有一个网络位置。当一个业务体量变大要部署到多个城市、多个机房时问题就来了用户怎么找到最近的机房传统做法有两种。一种是 DNS 调度你根据用户来源的 Local DNS 出口 IP在权威 DNS 上返回不同机房的 VIP这是“按域名解析粒度”做调度另一种是四层负载均衡在机房入口用 LVS/Nginx 之类的组件把连接分发到后端的多个实例这是“按连接粒度”做调度。ax 调度走的是完全不同的路线。它不改变业务数据包的寻址方式而是让同一个 IP 地址在多个物理位置被同时通告出去。你不需要为用户选择 IP互联网路由协议会主动把用户流量引到“距离更近”的那个节点。这里的“更近”不是地理意义上的距离而是路由协议算出来的最优路径。1.2 控制面和转发面的分工是理解 Anycast 的钥匙要理解 ax 调度必须先区分两个概念控制面Control Plane和转发面Forwarding Plane。控制面负责“说出去”——边界路由器通过 BGP 协议向运营商宣告路由这个 IP 前缀在我这里请把流量送给我。转发面负责“接住”——数据包到达路由器后路由器查 FIB 表把包按最长的前缀匹配送到对应的物理接口。Anycast 的核心玩法就是在多个地点的路由器上都宣告同一个 IP 前缀。这个前缀被宣告得越多互联网上就有越多的路径指向它。每个用户所在的运营商网络会根据自己的 IGP/BGP 选路结果选出它认为“最优”的一条路径。这个选择过程对业务方完全透明不需要你的应用参与任何决策。这个设计带来一个很有意思的结果ax 调度的切换速度甚至可以快过 DNS TTL。因为路由通告出了变化BGP 秒级收敛之后用户的下一个新连接就走了新路径完全不需要等缓存。而 DNS 调度通常要等 TTL 过期甚至还要等客户端和 Local DNS 的双层缓存刷新。生产环境里保守的 DNS TTL 通常在 60 到 300 秒这已经是比较乐观的数值了实际刷新时间经常拖到几分钟到几十分钟。Anycast 则把这个时间压缩到了几秒。1.3 和老办法比调度单位的差别在哪里我用一个表格把三种调度方式拉齐对比一下这样大家能更直观地看到边界在哪调度方式决策者粒度生效时间典型场景DNS 调度权威 DNS 按 Local DNS 出口 IP域名/记录级别受 TTL 和多级缓存影响分钟级各地返回不同 VIP/机房四层/七层负载均衡机房入口 LB 按四元组连接/会话级别毫秒级但只限于单机房后端多实例分发ax 调度Anycast互联网路由器按 BGP 最优路径IP 前缀级实质是分组级路由收敛时间秒级多地域就近接入所以你可以把 ax 调度理解为在“用户路由器到你的机房路由器”这一段把所有路径的选择权交给了互联网路由协议。它既不需要服务端记录用户来源也不需要提前准备各种切流脚本只要 BGP 通告正确用户流量就会“自动”流向规划中该去的位置。1.4 适合 ax 调度的业务长什么样Anycast 不是万能的它最适合那些会话短、可重试、无状态或者弱状态的协议。典型例子包括递归 DNS请求非常短客户端对重试天然友好Anycast 可以极大降低解析延迟。CDN 边缘节点用户访问静态资源天然可以重找节点。对象存储的全局入口上传和下载多为 HTTP 短连接加上重试机制后路径切换的影响很小。四层抗攻击清洗入口所有流量先引到最近的清洗节点清洗后再回源Anycast 在这里既是调度手段也是分布式 DDoS 缓解手段。一句话总结如果业务本身需要做到“多地接入且自动容错”ax 调度是一个值得认真考虑的底座方案。2. 分组路由如何决定“离谁最近”BGP 选路细节决定调度范围2.1 邻居类型决定第一跳的优先级不只是“远和近”很多人以为 Anycast 选路就是比地理距离谁近选谁。真实情况远没有这么简单。BGP 选路有一座完整的优先级大山排在最前面的几项是管理权重/Local Preference、AS Path 长度、MED、IGP 度量。生产环境里影响调度范围的第一个关键参数是你在每个节点与上游互联的邻居类型。通常我们把上游分成三类互通对等Peering、转接Transit和专线Private Interconnect。这三者在 BGP 选路里的初始待遇完全不同专线因为延迟、带宽、成本都可控通常 Local Preference 设得要更高一些比如 200普通的对等互联次之比如 150纯转接再低一些。这样设计的目的很简单同样一个前缀两个节点都在通告运营商路由器会优先走你的专线而不是绕到另一个节点再转回来。这一步在实际部署中很容易被忽略。很多人只想着“我在两个节点都广播用户自然就近”结果搞了半天发现所有流量都挤在专线或者某一个节点上。原因往往就是 Local Preference 的设计不符合预期BGP 决策走了优先级最高但不是你想要的那条路。2.2 AS Path 的加长与缩短如何把流量“拉”到目标节点BGP 选路一个非常核心的规则是 AS Path 越短越优。你可以利用这个规则手动调整调度范围如果希望某个节点的吸引范围更大就让它通告出去的路径尽量短如果希望某节点少接流量可以在通告路由时对特定上游做 AS Path Prepending也就是把自己的 AS 号重复若干次让路径看起来更长。假设你有上海和广州两个节点上海想承接华东和华北的流量广州承接华南和出海流量。在向华东某运营商通告时上海节点保持正常 AS Path广州节点可以对该运营商做路径加长。这样做的好处是即使该运营商的骨干网认为“到广州的路由跳数更少”在看到更长的 AS Path 之后依然会倾向于选择上海。这种人工干预的方式是日常调整 Anycast 流量分布最常用的手段之一。不过 AS Path 调整有一个明显副作用它会影响所有进入该节点的流量没办法只针对某一部分用户。如果你需要更精细的流量调度通常要结合 community、流量工程策略或者上游路由控策略一起用而不是单独依赖 prepend。2.3 路由过滤与安全边界ROA、前缀列表、黑洞路由Anycast 的前提是你在多个地方通告同一条路由但这同时也意味着你的 IP 前缀会被所有上游看见。一旦前缀被人错误广播或者恶意广播轻则流量被劫走重则业务整体不可用。所以 Route Origin AuthorizationROA和 RPKI 校验是上线 ax 调度之前必须做的一件事。简单来说ROA 是向外界声明“这个前缀属于哪个 AS允许它通告多少位长度的掩码”。上游路由器如果启用了 RPKI 校验发现你的路由与 ROA 不一致就会拒绝这条路由从源头阻止前缀劫持。除了 RPKI在边界路由器上还需要做一层防御性过滤。比较稳妥的做法是只接受上游邻居传输的、长度落在合理范围内的前缀在 outbound 方向上配置 prefix-list确保只通告自己的前缀和子前缀用 as-path ACL 限制对端 AS避免拿到或吐出奇怪的路由。以下是 Cisco 风格的一个示意配置思路是只通告自己的前缀同时给黑洞路由留一条专用出口ip prefix-list ONLY-MY-PREFIX seq 5 permit 203.0.113.0/24 le 24 ip prefix-list ONLY-MY-PREFIX seq 10 deny 0.0.0.0/0 le 32 route-map SET-ANYCASE permit 10 match ip address prefix-list ONLY-MY-PREFIX set community 64512:666 additive router bgp 64512 neighbor 192.0.2.1 route-map SET-ANYCASE out这里还把通告路由打上了 community 标记便于后续在内部或者上游层面做策略调控。黑洞路由是另一个经验在每台边界路由器上配置一条指向 Null0 的静态路由作为 /32 黑洞路由。当受到攻击时你可以把受害 IP 通过 RTBHRemotely Triggered Blackhole方式快速公告出去让所有上游瞬间把流量导进黑洞这是 Anycast 架构里很常见的抗攻击手段。2.4 收敛速度BGP 收敛并不快别把秒级当成必然前面我说 Anycast 的切换速度是秒级但这个“秒级”是有前提的。BGP 的收敛需要时间从一条路由失效到全网路由器重新收敛常规情况可能是几十秒复杂网络甚至能达到分钟级。要缩短收敛时间通常要做两件事一是用 BFDBidirectional Forwarding Detection配合 BGP让链路故障能在几百毫秒内被发现而不是靠默认的 keepalive 超时通常是 60 到 180 秒二是合理设计多级互联不要把所有上游都靠一根链路撑着。另一个经常被忽视的问题是BGP 收敛期间流量并不会立刻消失。它们可能会被中间路由器转发给仍在通告的另一个节点导致某一台边缘服务器瞬时涌入大量本不属于它的连接。这在后面“事故复盘”部分会看到不是理论风险而是真实事故。3. 两次 ax 调度事故复盘调度范围为什么会失效做网络这行最怕的不是出故障而是出故障后找不到头绪。下面这两个场景都是我实际在线上遇到过的也是 Anycast 架构最容易翻车的地方。3.1 事故一BGP 收敛期间的“流量海啸”那次事故发生在一次跨大区链路割接演练中。我们的拓扑是两个 Anycast 节点分别在北京和上海通过上游运营商的跨区专线互联。某次上海节点一个主用出口链路抖动BGP 开始 withdraw 部分路由结果在大概三分钟的窗口里几乎所有原本该落在上海节点的流量全部临时转移到了北京节点。表面上原因很简单上海的路由消失了路由收敛后流量改道北京。但真正的坑在后面——流量爆发式涌到北京节点后北京边缘服务器需要处理大量跨地域的 TCP 连接。那些原本是上海用户的长连接在客户端看来 IP 没变Anycast IP 都一样但 TCP 连接状态只存在于上海节点到了北京完全无法处理。客户端只能靠重试而重试建立的新连接又被 CDN 层的健康检查误判导致一堆“连接超时”告警。我们当时的排查过程是先看边缘服务器的连接跟踪表发现 nf_conntrack 条目暴涨然后看 BGP 邻居状态确认是路由 withdrawn最后逐个上游确认收敛完成。复盘时我们意识到根因不是 BGP withdraw 本身而是我们没有在收敛过渡期抑制后端业务的连接处理也没有为“路由收敛期间的临时跨节点流量”做兜底比如在边缘节点临时开启 SYN Proxy或者将健康检查阈值临时调高。3.2 事故二分组级调度与连接级会话不一致第二个事故更隐蔽也更难排查。现象是某节点上了 Anycast 之后用户访问服务时出现间歇性“握手超时”但换一个网络环境又完全正常。抓包发现用户发出去的 SYN 到达了 A 节点但 SYN-ACK 却从 B 节点返回。客户端觉得这个包不对直接丢弃导致握手永远无法完成。再往深挖问题出在运营商侧用户的上行流量和下行流量走了不同的路径或者运营商在中间设备上做了基于四元组的一致性哈希但哈希结果在两个方向上不一致导致同一连接的前后报文被送到了不同节点。Anycast 在入口处是“分组级调度”它不感知连接也没有办法保证一条 TCP 连接的两个方向都落在同一个节点。只要中间网络设备行为特殊或者你的业务没有在边缘做好连接状态的粘结逻辑这种“同一连接跨节点”的情况就有可能出现。这次的修复策略不是靠 Anycast 本身而是在边缘层增加了“连接归属判定”如果发现进来的 SYN 落在本节点但后续 ACK 却被上游路由到了别的节点那么本节点通过后端的会话同步通道通知另一节点代为响应或者直接为关键业务增加 TCP 快速重试机制让客户端在遇到异常 SYN-ACK 时立刻重新发 SYN。实践中后者更简单因为 Anycast 的切换很快客户端只要愿意重试基本下一跳就好了。3.3 复盘结论调度范围和业务会话是两件事这两次事故教会我一个词调度域分离。ax 调度只负责“把数据包送到哪个节点”它不负责“连接建好后能不能续上”。连接能不能续上取决于你的业务层是否对跨节点切换有容忍机制。DNS 场景天然没问题因为 UDP 请求发出去了就是出去了丢了客户端会重发而 TCP 长连接、WebSocket、以及有状态协议就要认真评估是否能在路由切换的瞬间接受连接断开和自动重连。在生产环境里我们后来定了一条规矩任何上 Anycast 的业务都必须自带客户端重试机制或者服务端会话保持至少 60 秒以上。做不到的就不要用 Anycast这是最根本的边界。4. 上线 ax 调度的实操路线从两阶段灰度到切换演练如果你已经决定要上 ax 调度不要急着把前缀全网广播。我在项目里总结了一套相对稳妥的上线流程按步骤走可以大幅降低踩坑概率。4.1 第 0 步先清理原站流量和 DNS 依赖很多人忽略这一步直接加 BGP 通告结果发现原站 IP 还在某些客户端缓存里没走干净或者 CNAME 解析链还指向旧的 GLSB 设备导致流量模型混乱。建议先把对外服务从依赖“CNAME 解析到某单点 VIP”改造成“A 记录直接指向 Anycast IP”。DNS TTL 提前降到 60 秒甚至更低并观察至少 24 到 48 小时确保解析量平稳、缓存逐渐过期。把这一步做完后面切 BGP 才不会被 DNS 缓存问题混淆。4.2 两阶段灰度先“出国”再“跨大区”第一次通告不要把所有上游全部对起来。我常用的做法是分两阶段第一阶段只在一个节点的部分中转链路Transit上通告比如只面向海外三个运营商。这个阶段的目的不是承载太多流量而是验证 BGP 路由本身的正确性观察路由表拉升、前缀是否被接收、有没有收到异常告警。第二阶段确认第一阶段没问题后再逐渐放开其他节点和对等Peering链路让流量按照设计的 Local Preference 落到目标节点。这样做的好处是即使配置有问题你影响的也是小范围流量而且可以通过把该前缀在一条链路上撤回快速回滚。相比全网一次性广播风险面小了好几个数量级。灰度期间需要盯几个关键指标每个节点收到的流量曲线、BGP 前缀数量、flap 次数、上游的过滤告警。不要只盯着带宽BGP 路由条目的波动往往比带宽更能提前告诉你问题。4.3 黑洞路由预演与真实流量验证有一个技巧很多团队不重视在正式放量之前先用黑洞路由把所有流量导走验证“应急链路是通的”。具体操作是所有边界路由器上先把该前缀引入黑洞然后观察全网流量是否掉到接近零再逐步放行。这一步看起来多余但它能确认你未来发生攻击或故障时“一键拉黑”的效果是真实有效的而不是等出事时才发现黑洞配置错误。放行之后再配合从多个外部探测点访问服务。不要只用阿里/腾讯/电信联通的 ping 拨测这些地点往往本身就有多条路径汇聚看不出真实效果。建议至少找三个不同地区的小型 VPS、家庭宽带、以及不同运营商网络做联合验证然后看 traceroute 的最后一跳是否落在预期节点。4.4 健康探测与上游失效的取舍Anycast 节点宕机也不是直接就不通了而是要等上游 BGP 收敛流量才会完全切走。这中间有一个非常尴尬的窗口路由器还认为该节点存活但后端应用已经无法响应。我们给边界路由器和后端健康检查之间做了一个联动后端探活失败达到阈值时边界路由器立刻撤回对应前缀而不是被动等上游探活失败。这里还要考虑一个细节上游或对等方是否在收货后会立刻做策略路由。有些运营商会配置最小前缀长度限制或者对某些前缀做本地偏好设置导致你的路由效果打折。接入前最好跟对方网络团队确认好对这些前缀的常规处理方式。4.5 上线验收清单最后分享一个我们在项目验收时固定的清单你可以直接拿去用BGP 会话状态全部 Established无 flaps。每个节点广播的统一前缀数量一致没有被上游过滤掉。各运营商探测节点的 traceroute 最后一跳符合预期节点分布。黑洞路由拨测有效流量可以被瞬间清零。灰度期间各节点带宽增长幅度未超过预估上限。后端健康检查联动超时时间合理不会出现误拉路由的抖动。证书/SNI 等业务校验在多节点无差异避免用户访问到一个节点后因证书不匹配失败。5. 运营中的三个边界问题哪些情况不该上 ax 调度Anycast 用顺手之后大家容易产生一种错觉“什么业务都能往上放”。但运营久了你会知道这个架构在几个场景里其实是硬伤。5.1 NAT 与 SNAT 对返回路径的影响如果你在边缘节点做了 NAT比如用户流量到达边缘后源地址被转换成内网地址再回源那么问题就来了返回流量必须回到边缘节点但 Anycast 只管入口不管出口出口路径往往是另一条路由。一旦返回流量没有回到同一个边缘节点连接就断开了。为了避免这种情况很多服务在边缘会用 DSR直接服务器返回模式后端服务器直接拿着原始目的 IP 把响应发回去不经过边缘节点 NAT但这样又要求后端服务器学习和维护 ARP/路由表实现复杂度高。对于用 SNAT 四层负载均衡的常规架构Anycast 只适合做入口接入层不能指望它同时解决出口路径问题。这一点在规划阶段就必须想清楚。5.2 IPv6 下的 Anycast 注意事项IPv6 和 IPv4 在 Anycast 上的表现并不完全一样。IPv6 的临时地址Privacy Extensions会导致同一个客户端源地址经常变化再加上很多 IPv6 网络路径没有 IPv4 那样成熟的选路策略你在 IPv6 上做 Anycast 的流量分布可能比 IPv4 更不均匀。另外互联网上 IPv6 前缀劫持的检测机制没有 IPv4 那么成熟ROA 在 IPv6 上的覆盖率和实施率也低一些。如果你的业务对 IPv6 依赖很强建议把 IPv6 的 Anycast 方案先定义为“尽力而为”不要一开始就指望它达到和 IPv4 同级别的调度精度。5.3 什么场景我不建议上 ax 调度长时间存活的长连接业务比如 WebSocket、消息推送。虽然客户端可以重连但秒级中断对实时性要求高的业务是致命的。需要固定出口 IP 的业务FTP 主动模式、部分第三方回调、白名单鉴权这些天然就和 Anycast“多入口”特性冲突。强一致性的数据库写入链路本身就需要通过专线/内网保持在同机房Anycast 帮不上忙反而可能把入口流量导到离数据库较远的节点增加网络延迟。对延迟极敏感但节点就近性又不如专线的业务比如跨境金融交易行情它们要求的是极致的路径确定性而不是动态路径切换。还有一个我在实际运营里反复确认过的体会Anycast 适合做“入口调度”但它不代表网络链路质量本身。如果你的某个地域没有优质的互联链路Anycast 只能让用户进入最近的节点却无法改变最后一段链路的拥塞状况。所以基础设施质量的底子还是要靠专线、多线接入和内部骨干优化来打ax 调度是在这个底座之上的一层聪明调度而不是替代品。最后分享一个选型时的判断标准任何想要上 ax 调度的业务先回答三个问题——丢一个包用户能不能接受断一次连接会不会有资损跨节点切换后管不管得住如果任何一个问题的答案是有风险那就先考虑混合方案比如 DNS 调度为主、Anycast 兜底而不是一上来就全量切换。这套思路帮我在好几个项目里避免了返工希望能给你省掉一些试错时间。
返回列表