Backend

国内访问 GitHub Pages 又慢又不稳,我先怪 DNS 污染,实测后发现是线路

1876 字约 7 分钟

摘要一个托管在 GitHub Pages 上的静态站,国内用户反映慢、时好时坏。助手第一个回答是 DNS 污染,换自己的域名就行。我追问了一句,它拿我的机器实测,结果解析完全正常,问题在海外节点的线路上,换域名解决不了。

我们有一个托管在 GitHub Pages 上的静态站,群里的人反映国内打开又慢又不稳,有时候干脆打不开。我问助手有什么办法能让国内直接访问,或者至少快一些。

第一个回答:DNS 污染

助手先看了站点代码,没有用 Google Fonts、jsdelivr 这类国内常被墙的外部资源,评论区是按需加载的,加载失败不会卡住页面。它的结论是慢不在代码里,而在 *.github.io 这个域名本身:国内常遇到 DNS 污染,GitHub Pages 用的 CDN 也没有国内节点。

它按投入由小到大列了三个方案:

  1. 买一个域名,绑到 GitHub Pages。能避开 github.io 的 DNS 污染,但服务器还在海外,速度提升有限。
  2. 自己的域名加海外托管平台,比如 Vercel、Netlify、Cloudflare Pages。不用备案,但平台自带的域名在国内基本被墙,必须绑自己的域名,晚高峰仍然会慢。
  3. 域名备案加国内 CDN,能真正做到秒开,门槛最高,个人备案一般要先买一台国内服务器,流程 1 到 3 周。

我对“DNS 污染”这个说法有疑问,就追问了:DNS 污染是什么意思,为什么用自己的域名就不会了?是指用自己的域名在 Cloudflare 上做解析吗?

实测之后,它更正了自己

助手这回没有再解释概念,而是拿我的机器实测了一遍,然后说:你们网站现在的问题其实不是 DNS 污染。

DNS 污染是防火墙盯着跨境的 DNS 查询,一旦查询的域名在名单上,就抢在真实回复之前塞一个假 IP 回来,浏览器拿着假 IP 去连,自然打不开。关键在于,它是按域名匹配的。

它分别用 114、阿里、腾讯三个国内 DNS,和境外的 8.8.8.8、1.1.1.1 解析这个站的域名,结果全部是 GitHub 的真实 IP,没有被污染。真正的问题出在连接上,绕过代理直连的结果是:

  • 首页加载三次,分别用了 2.2 秒、3.7 秒、2.0 秒,其中建立连接一次就花了 2.3 秒。
  • ping GitHub Pages 的服务器,延迟约 300ms,丢包 50%。

这些 IP 属于 Fastly 的海外节点,国内到那边的线路又远又不稳。我平时开着代理,所以浏览器里访问感觉很快,没开代理的访客看到的就是上面的速度。

那自己的域名有什么用

助手更正了第一个回答里的说法:

  • 自己的域名不在封锁名单上,所以能避开专门针对 github.io 这个名字的干扰。
  • 但按标准做法,自己的域名要 CNAME 到 xxx.github.io,国内 DNS 解析时还是要去查一遍 github.io,污染严重的时候这一步照样可能被抢答。
  • 更重要的是,最后连的还是那几个海外 IP,300ms 的延迟和丢包不会因为换了域名而改善。

所以只绑域名、继续用 GitHub Pages 托管,解决不了现在的慢。

至于 Cloudflare,“在 Cloudflare 上做解析”其实有两种意思。只用它管 DNS(灰色云朵),DNS 放在哪家基本和污染无关,污染只看被查询的域名。开代理(橙色云朵)是让流量改走它的 CDN,免费版在国内通常被绕到美国节点,经常比直连 GitHub 还慢,而且开了以后 GitHub Pages 申请 HTTPS 证书也容易出问题,不推荐。

这里先后出现过两个说法

助手的第一个回答把原因归在 DNS 污染上,这是一个常见但笼统的解释。真正有用的是第二个回答里的做法:用不同的 DNS 解析一遍,再测延迟和丢包,把“解析”和“连接”分开看。以后遇到访问慢,先判断是哪一步慢,再决定要不要换域名。

我其实有一台香港的机器

聊到这里我才想起来,我有一台放在香港的机器,也有域名。助手顺手测了一下:从我这里 ping 过去 29ms,零丢包,对比 GitHub Pages 的 300ms 和 50% 丢包,差了一个数量级。香港的机器不用备案,国内直接访问,线路也好。

于是这个静态站先保持不变,我打算顺便把要做的论坛放在这台机器上。静态站慢的问题,倒是有了更准确的认识:要快,只能把站点放到离国内用户近的节点上,也就是备案加国内 CDN。

后来:福建的用户说连不上

论坛上线后,有人反映福建那边连不上香港这台机器。我让助手测一下国内各地的连通性。

我的电脑在上海电信,直连正常,ping 28ms 零丢包,22、80、443 端口都通。助手又用 itdog 和 Globalping 的国内探针做了测试,Globalping 没有福建的节点,itdog 有。

测试电信·厦门联通·宁德移动·福州
ping50ms60ms70ms
TCP 44350ms60ms70ms
打开论坛首页0.1 秒0.2 秒0.3 秒

另外泉州电信的节点打开网页 0.21 秒。itdog 的 200 个节点里,国内的这几项测试都没有超时,只有合肥电信一个节点的网页测速花了 9.4 秒,应该是那个节点自己的偶发问题。Globalping 上 20 个国内节点,三网和云厂商都有,打开论坛全部返回 200,建连 10 到 50ms,加密握手 50 到 140ms。服务器负载 0.35,连接队列没有溢出,也没有丢弃新连接。

所以福建三家运营商没有被整体拦截,服务器本身也没问题,问题多半出在那位用户自己的网络上。助手列了几种常见原因:

  1. 校园网(教育网)。教育网到香港的线路经常很差,甚至不通,而测速节点都不在教育网里,测不出来。群里大多是学生,这个可能性最大。
  2. 当地运营商对未备案网站的拦截,可能只在某个地市或某种宽带上有,测速节点刚好没覆盖到。
  3. 本地 DNS 没有解析到正确的 IP。

要定位的话,请那位用户提供三样东西:用的是什么网络(校园网、家庭宽带还是手机流量,手机流量能不能打开)、打开时报什么错(一直转圈、连接被重置还是证书错误),以及在那台电脑上运行 nslookup 看域名解析到哪个 IP、curl -v 看卡在哪一步。

小结

  • 国内访问慢,先区分是解析慢还是连接慢。用几个不同的 DNS 解析一遍,能很快排除污染。
  • 绑自己的域名,只能避开按域名的干扰,改不了最后连的是哪个节点。
  • “某地连不上”要用多地探针测,但探针都不在教育网、不是用户的宽带,测不出来的问题要让用户自己提供网络类型和报错。
数据只代表测试时的情况

以上延迟和丢包都是我当时在一个运营商下测的,不同运营商、不同时间段差别很大。福建那位用户的最终原因,我这里没有结论。

评论