同一个IP地址在东京、法兰克福和圣保罗同时宣告,用户访问时并不会出现路由混乱,靠近用户的路由器会依据BGP路径信息把请求导向其中一个节点。这套机制背后是Anycast寻址与BGP路由协议的协作,也是很多CDN骨干网实现全球加速的基础。要理解它,得先放下对“一个IP只能对应一台服务器”的直觉。Anycast允许多台地理位置分散的服务器共享同一个IP,BGP则负责在不同自治系统之间传播该IP的可达信息。

Anycast与BGP的协作原理
BGP运行在自治系统之间,核心任务是传递网络层可达信息。当某个CDN节点位于AS65001,它要把203.0.113.0/24这个Anycast前缀发布给上游运营商AS65002时,会在BGP更新报文中携带AS_PATH、下一跳等属性。其他地方的路由器收到多个相同前缀的路由后,会通过比较本地优先级、AS路径长度、MED值等选出一条最优路径。东京用户访问那个Anycast IP时,由于东京节点宣告的AS_PATH更短或本地优先级更高,流量自然进入东京机房。
这个过程类似于在多个机场使用相同的航班号,旅客从不同城市出发,值机系统会把票按最近登机口分配。BGP没有全局流量调度中心,它依赖分布式路由策略。CDN通常在多地区部署节点,每个节点通过不同上游运营商宣告相同前缀,用户到节点的路径由运营商骨干网自动选出。比如法兰克福用户访问时,BGP选择法兰克福节点;一旦该节点故障,路由会被撤销,BGP收敛到下一个可用节点。这样实现了故障转移,但收敛时间受制于BGP和链路状态。
以下是一段使用BIRD的简化BGP配置,展示节点如何把203.0.113.0/24宣告给上游,同时过滤掉其他无关前缀:
# /etc/bird/bird.conf
router id 192.0.2.1;
protocol device {
scan time 10;
}
protocol kernel {
export none;
}
protocol bgp upstream1 {
local as 65001;
neighbor 203.0.113.1 as 65002;
export filter {
if net ~ [ 203.0.113.0/24 ] then accept;
reject;
};
import all;
}
这个配置里export filter只允许Anycast前缀发送出去,避免把内部路由泄漏到公网。BGP的多路径功能也可以让同一前缀从多个邻居接收时同时放进转发表,配合等价路径实现负载分担。但ECMP在Anycast场景下会带来一个新问题:一个TCP连接的不同数据包可能被转发到不同节点,导致连接状态不完整。因此无状态内容分发通常比长连接业务更适合直接用Anycast。
CDN骨干网Anycast节点部署实践
部署Anycast节点前要把地址规划清楚,不能直接拿普通公网IP就宣告。通常CDN会为Anycast前缀单独划分一个或多个/24网段,每个节点内部用回环地址绑定该前缀,然后通过物理接口与多个上游建立BGP会话。服务器上并不需要配置复杂路由,只需要把节点IP配置在loopback,BGP路由器再负责发布。这样当节点故障时,路由器会检测到BGP会话断开并撤销路由。
节点选型上,同城多节点可以连接到不同运营商,减少单运营商故障影响。海外节点还要考虑IP地址在不同地区的路由策略差异。某些国家或地区运营商可能不使用最佳AS路径,而是基于商业关系选择路由。因此实际部署后常常需要对主要运营商做主动测量。可以用脚本定期查询路由表,判断当前节点是否有效接收到了远端流量。下面这段Python脚本调用birdc命令,检查指定前缀是否出现在BGP表中:
import subprocess
def check_anycast_route(prefix):
try:
output = subprocess.check_output(
["birdc", "show", "route", "for", prefix],
timeout=5
)
text = output.decode()
if prefix in text:
return True
return False
except subprocess.CalledProcessError:
return False
if __name__ == "__main__":
route_ok = check_anycast_route("203.0.113.0/24")
print("Anycast route present:", route_ok)
这段脚本适合放在监控系统里定时执行。如果返回False,说明本地BGP可能没有学到Anycast前缀,需要检查上游会话。除了路由可见性,还需要关注回程路径。用户请求到达Anycast节点后,响应包可能走另一条路径返回,如果回程经过不同的网络甚至被黑洞,用户体验就会异常。所以节点不仅要发布Anycast前缀,还要确保默认路由和上游链路都能正常回源。
实际部署中还会遇到MTU问题。CDN节点和用户之间插入隧道或加密时,如果MTU设置不当,Anycast流量会被分片或丢弃。建议统一调整MSS,尤其是使用IPsec或VXLAN的骨干网。节点健康检查也要区分控制面和数据面:BGP会话在但应用进程挂掉时,路由不会撤销,此时需要应用层健康检查主动触发路由切换。
健康检查与流量调度
BGP收敛速度在秒级甚至更慢,对于实时业务来说还是不够快。引入BFD可以让路由器在毫秒级检测到邻居故障并撤销路由。BFD独立于BGP,通过快速发送控制报文判断链路和转发面是否正常。下面是一个在Cisco IOS上启用BFD的参考片段:
interface GigabitEthernet0/1 ip address 203.0.113.2 255.255.255.252 bfd interval 300 min_rx 300 multiplier 3 router bgp 65001 neighbor 203.0.113.1 fall-over bfd
BFD的探测间隔和倍数需要根据链路质量调整。太激进会误报,太慢又失去意义。对于跨洲链路,间隔一般可以放宽到500毫秒或1秒。CDN通常还会同时配置BGP community,把不同节点的路由标记为不同优先级。比如主节点使用社区值65001:100,备用节点使用65001:200,上游运营商根据社区调整local pref,实现主动流量调度。
流量调度还可以结合应用层监控。比如某个节点虽然BGP路由正常,但缓存命中率下降或者回源链路拥塞,此时可以主动停止向该节点发布Anycast前缀,把流量让给其他节点。操作上可以使用路由器的route-policy或直接关闭BGP会话。自动化系统分钟级执行一次检查,发现节点性能异常就修改社区值,让周围运营商逐步把流量引到其他入口,避免生硬切换造成TCP连接全部重置。
另一类常见问题是非对称路径。当应答包从另一个节点返回时,中间路由器可能因为反向路径转发检查丢弃数据包。Anycast环境下要确保开启宽松RPF或根据路由表正确放行。对于HTTP内容,可以使用X-Forwarded-For头传递用户真实IP,但需要在节点之间同步日志和缓存状态。因为同一用户连续请求可能被路由到不同节点,如果节点间缓存不一致,会返回不同版本的内容。
性能对比与选型建议
Anycast和GeoDNS是两种主流的全球流量调度方案。GeoDNS通过权威DNS根据用户来源返回不同节点的IP,调度粒度较细,但切换依赖DNS TTL,通常需要几十秒到几分钟。Anycast切换在网络层完成,故障收敛可以压到秒级,但调度粒度较粗,无法按业务维度精准控制。很多CDN采用混合方案:Anycast承载入口流量,GeoDNS负责API或登录等需要稳定会话的业务。
| 对比项 | Anycast+BGP | GeoDNS |
|---|---|---|
| 切换速度 | 秒级到亚秒级 | 受TTL影响,分钟级 |
| 调度粒度 | 按网络前缀 | 按用户DNS出口 |
| 状态连接 | 适合无状态内容 | 适合有状态服务 |
| 部署复杂度 | 较高,需BGP和IP资源 | 较低,主要配置DNS |
从骨干网角度看,Anycast的优势在于用户和边缘节点的连接由运营商选路完成,不依赖第三方DNS递归解析器的位置。很多移动网络用户的DNS出口与真实IP位置不一致,GeoDNS容易把用户调度到错误区域;Anycast则按数据包的实际转发路径选择入口,通常更贴近用户网络。不过Anycast需要较大的IP地址块和AS号,对运维能力要求更高。
在构建CDN骨干网时,可以先选择少量核心区域部署Anycast入口,观察各运营商的路由选择是否符合预期。如果发现流量过于集中,可以通过AS路径预置让部分区域的节点提高优先级。逐步把静态内容、图片和下载类业务切到Anycast,长连接和写操作保留在DNS调度或专用IP上。最终形成分层的加速网络:边缘Anycast负责就近接入,骨干专线完成跨区域同步,回源层通过私有BGP策略控制带宽和成本。
总体而言,Anycast与BGP不是新概念,但把它们用好需要理解路由协议的行为边界。不要期待BGP会像全局负载均衡器那样精确分配百分比流量,它的优势在于极快的故障转移和与互联网拓扑天然贴合。配合健康检查、BFD和应用层调度,CDN骨干网可以构建出稳健且低延迟的全球加速能力。