CDN 调度策略:三种核心方法

这一讲我们聊聊 CDN 调度策略。说白了,就是怎么把用户拽到最近的节点。

我见过不少团队,上来就搞 Geo 调度,觉得地图上离得近就是快。结果呢?延迟反而变高了。为什么?因为物理距离和网络距离,其实是两码事。

我个人习惯,先把三种策略吃透,再看场景选方案。你想想看,调度策略不对,后面缓存、加速全白搭。

基于地理位置调度

这是最直觉的方案。用户 IP 一过来,查归属地,然后分配最近的节点。

具体怎么干?

  • GeoIP 数据库:维护一份 IP 段到地理位置的映射表。
  • 静态分配:用户在北京,就给北京节点;用户在纽约,就给纽约节点。
优点:实现简单,查询快,不依赖网络探测。
缺点:IP 归属地可能不准。跨运营商调度更是灾难,比如电信用户被分到了联通节点。

我记得有一次,某客户反馈华南地区用户访问奇慢。我查了下调度日志,发现那些用户的 IP 被 GeoIP 误判成了华北,全打到了北京节点。广州到北京,跨了半个中国,延迟当然高。

避坑指南:我曾经用过一个第三方 GeoIP 库,结果大量海外 IP 被判定为国内。后来我养成了习惯,一定要搭配纯真 IP 库或者 MaxMind 的商业库做交叉校验。

另外,Geo 调度很难处理移动网络。用户在地铁上,IP 归属地可能是另一个城市。你想想看,这种场景下纯靠 Geo 调度,基本就是碰运气。

维度Geo 调度说明
数据源IP 归属地库需要定期更新
动态性无分配结果固定
适用场景静态资源、跨洲缓存对延迟不敏感的场景

基于网络延迟调度

这才是真正意义上的「就近」。我不看你在地图上离我多远,我只看你到我各个节点的网络延迟是多少。

怎么做?

  • 探测节点:在 CDN 边缘节点部署探测程序。
  • 主动探测:定时向用户 IP 或用户附近的 DNS 发送 ICMP/HTTP 探测包。
  • 被动采集:收集真实用户连接时的握手延迟、建连时间。
  • 动态建表:维护一张「用户 IP 段 → 各节点 RTT」的延迟表。

调度时直接查这张表,挑 RTT 最小的节点返回。

小技巧:我建议不要只依赖单次探测。网络抖动很常见,可以用滑动窗口取过去 5 分钟的 P99 延迟,这样更稳定。

延迟调度的精度高,但成本也高。你想想看,全球几百个节点,每个节点都要维护一张延迟表,数据量巨大。而且用户 IP 在变,探测不能停。

我经历过一个案例:某游戏公司用纯延迟调度,结果华北用户被分配到了华南节点。为什么?因为当时华南节点一条海底光缆断了,但探测程序没感知到,RTT 数据还是老的。直到用户投诉,我们才发现延迟表更新有 10 分钟的误差。

避坑指南:我曾经因为探测间隔设置太长,导致延迟表严重滞后。后来我把探测周期从 5 分钟改成了 30 秒,误调度率降了 70%。


# 探测逻辑伪代码
def select_best_node(user_ip):
    delay_table = get_delay_table()
    # 取过去5分钟 P99 延迟
    min_rtt = float('inf')
    best_node = None
    for node in all_nodes:
        rtt = delay_table.get_p99(user_ip, node)
        if rtt < min_rtt:
            min_rtt = rtt
            best_node = node
    return best_node

基于负载的调度

前面两种策略只考虑「离得近」,但没考虑「挤不挤」。你想想看,如果某个节点快被挤爆了,就算离得再近,用户体验也一塌糊涂。

负载调度要解决的就是这个问题。

  • 实时采集:每个节点上报 CPU、内存、带宽使用率、并发连接数。
  • 负载权重:根据健康度给节点打分。
  • 流量分配:把新用户优先调度到低负载节点。
核心逻辑:不是「最近最好」,而是「最近且最空」最好。

我记得在某大促期间,华东节点因为带宽打满,响应时间飙升到了 2 秒。如果只看延迟,它可能还是离用户最近的。但负载调度及时发现健康度下降,把流量切到了华中节点,整体延迟反而降到了 300 毫秒。

负载调度一般和前面两种策略组合使用。我的做法是:先用 Geo 或延迟选出一批候选节点,再根据负载评分做二次筛选。这样既保证了物理距离不绕路,又避免了单节点过载。

策略数据源动态性适用场景
Geo 调度IP 库低静态资源、跨洲
延迟调度网络探测中动态内容、视频
负载调度节点指标高高并发、大促
CDN 调度策略核心逻辑 用户请求 DNS 调度器 Geo 调度器 IP 归属地 → 最近节点 延迟调度器 网络探测 → 最低 RTT 负载调度器 节点健康度 → 最空闲 返回最优节点 IP 实践中常将两种或三种策略组合,先筛选再评分,避免单一策略带来的缺陷

总结一下我的经验:

  • 纯 Geo:简单但粗糙,适合不差钱、用户分布广的场景。
  • 纯延迟:精度高,但代价大,延迟表更新要快。
  • 加负载:防止雪崩,特别是大流量时一定要加。

你想想看,一个用户跑了几千公里到你的 CDN 节点上,结果那个节点快挂了。这不白费力气吗?所以我的建议是:延迟做初筛,负载做终选。

一句话总结:没有完美的调度策略,只有适合业务的组合方案。不要只盯着一种策略,多维融合才是最优解。

好了,这部分我们先聊到这。实际项目中,你可以根据业务特点组合使用这些策略。