分布式部署 cloudflared 让访客就近回源,进一步提升访问速度

2023-11-27 更新:这种方法似乎只能保证有源站的国家(比如美国和日本,那只有美国和日本的访客)可以比较稳定就近回源,我在 Cloudflare Community 上发了帖子: https://community.cloudflare.com/t/tunnel-cannot-route-to-geographically-closest/537965/8

目前如果希望稳定就近回源,或者说可控的话,除了用 IPv6 Anycast 以外似乎还可以使用 Worker 回源,相关博客: 使用 Cloudflare Workers 在边缘让服务就近回源——降低全球平均延迟

在之前的文章「搭建 Cloudflare 背后的 IPv6 AnyCast 网络」中我们知道:

一般的,Cloudflare 回源的方式是由访客命中的数据中心进行回源

假设你的站点服务器位于美国,那么一个日本用户在访问你的域名的时候会首先访问到 Cloudflare 在日本的数据中心,然后由 Cloudflare 日本走公网反向代理到你的源站(也就是美国的机器上)获取内容。

如果你的站是 Stateless 的,或者说很好扩展的话,在使用 Cloudflare 的情况下其实并不能做到在多个区域中部署,并在使用同一个域名的情况下做到访客就近回源,具体来说,我们想达到的效果是如下的:

  • 三台机器 A,B,C 分别位于美国,日本,法国,上面跑着一个监听在 localhost:80 端口的服务
  • 使用同一个域名 tunnel.nova.moe,并使用 Cloudflare 作为 CDN
  • 大部分美洲用户访问后应该看到 A 机器上的内容,大部分亚洲用户访问后应该看到 B 机器上的内容,大部分欧洲用户访问后看到 C 机器上的内容

在我们开始讲这个实践之前读者可以想想看如果你的业务有类似的需求,你会怎么设计?以下我列举几个可能性

  • 使用非 Cloudflare 的 CDN 并针对不同的 IP 创建域名(比如 us.nova.moejp.nova.moe 等) ,这样我们可以用别的自带分区解析的服务商,让不同区域的用户解析到不同的域名上
    • 这么做的话费用就是 CDN 流量费 + DNS 服务费
  • 使用 Cloudflare 的 CDN 并使用 SSL for SaaS,创建一个单独的域名针对不同 IP 创建域名,然后找一个自带分区解析的服务商,让不同区域的用户解析到不同的域名上
    • 这么做的话费用就是 DNS 服务费
  • 买 Cloudflare 的 Load Balancing 服务,5USD/mo 起步,多 Region 需要购买 Traffic Steering,额外 10USD/mo

有没有什么更加廉价的解决方案?

Cloudflared

通过 Cloudflared 的文档: Tunnel availability and failover · Cloudflare Zero Trust docs 中我们可以看到这么一段:

By design, replicas do not offer any level of traffic steering (random, hash, or round-robin). Instead, when a request arrives to Cloudflare, it will be forwarded to the replica that is geographically closest.

这就给了我们操作的空间,思路如下:

  • 创建一个 Tunnel
  • 在多个区域的机器上都使用同一个 Tunnel 的配置来连接 Tunnel
  • 和往常一样配置 Tunnel 信息
  • 保证多个区域的机器的服务监听在同一个端口
  • 成了

我们来看看实际操作起来是怎么样的,首先是创建 Tunnel 并在机器上连接 Tunnel

这里为了测试我找了两个分别位于新加坡和德国的机器用来演示,每个机器上都安装了 Nginx 并修改了一下 Example Page,在配置的时候我们可以看到已经有两个 Connector 在线了

接下来就是熟悉的配置环节,由于过于简单这里就没有截图了。

配置好之后我们来验证一下吧,这是从日本访问:

这是从瑞典访问:

可以看到我们在使用相同域名的情况下已经可以做到让 Cloudflare 回源到最近的数据中心了,位于欧洲的访客再也不用让 Cloudflare 公网回源到新加坡去拿数据了,这个时候对于我们的 Web App 来说,只要解决好后台数据同步的问题(或者说如果就是一个 Stateless 的 App 的话),已经可以在没有额外开销的情况下进一步减少不同区域访客的访问延迟了。

此外,即使你有部分机器不可用,只要还有一个机器活着,整个站点还会保持可用状态,因为:

If that distance calculation is unsuccessful or the connection fails, we will retry others, but there is no guarantee about which connection is chosen.

而且这一切还都是免费的!

不得不感慨,「At Cloudflare, we have our eyes set on an ambitious goal — to help build a better Internet.」,真的不仅仅是一句口号。