问题起因🌲
最近在做一个web项目,前两周打开前端调试突然发现网站渲染失败,F12查看发现部分CSS和JS的CDN资源加载不出来,均来自于cdnjs.cloudflare.com
这个域名,当时刚好碰上Cloudflare出现了重大事故(详见Cloudflare 刚刚这波挂得挺惨的和Cloudflare outage on June 21, 2022),于是当时想着可能是Cloudflare的问题,过几天应该就好了吧?😄
结果昨天晚上去看还是加载失败,就开始自己定位问题。😓
问题定位🔍
Ping
首先看看域名能不能ping通
1 2 3 4 5 6 7 8 9 10 11
| $ ping cdnjs.cloudflare.com PING cdnjs.cloudflare.com (127.0.0.1): 56 data bytes 64 bytes from 127.0.0.1: icmp_seq=0 ttl=64 time=0.048 ms 64 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.063 ms 64 bytes from 127.0.0.1: icmp_seq=2 ttl=64 time=0.113 ms 64 bytes from 127.0.0.1: icmp_seq=3 ttl=64 time=0.195 ms 64 bytes from 127.0.0.1: icmp_seq=4 ttl=64 time=0.201 ms ^C --- cdnjs.cloudflare.com ping statistics --- 5 packets transmitted, 5 packets received, 0.0% packet loss round-trip min/avg/max/stddev = 0.048/0.124/0.201/0.064 ms
|
这个域名居然被解析到本地回环地址127.0.0.1
了,好奇怪啊!看上去像是DNS解析出错了。接着查看本机网络配置的DNS服务器,发现DNS地址是192.168.1.1
,emmmmm,和网关地址一样,看来这个地址是DHCP动态下发的我没改过,理论上是没有问题的,整个局域网内的设备都从网关获取DNS既方便修改也有利于DNS缓存命中。
DNS resolve
理所当然,先确认一下是不是DNS解析的问题。
运行一下nslookup命令
1 2 3 4 5 6 7
| $ nslookup cdnjs.cloudflare.com Server: 192.168.1.1 Address: 192.168.1.1
Non-authoritative answer: Name: cdnjs.cloudflare.com Address: 127.0.0.1
|
或运行一下dig命令
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| $ dig cdnjs.cloudflare.com
; <<>> DiG 9.10.6 <<>> cdnjs.cloudflare.com ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 7424 ;; flags: qr aa rd; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0 ;; WARNING: recursion requested but not available
;; QUESTION SECTION: ;cdnjs.cloudflare.com. IN A
;; ANSWER SECTION: cdnjs.cloudflare.com. 300 IN A 127.0.0.1
;; Query time: 11 msec ;; SERVER: 192.168.1.1#53(192.168.1.1) ;; WHEN: Mon Jul 04 19:36:14 CST 2022 ;; MSG SIZE rcvd: 54
|
果然,都是解析到了127.0.0.1
。注意看Server都是192.168.1.1
网关地址,这里有一个疑惑,是不是网关上面的DNS配错了呢?
我用的网关是深圳电信的天翼网关3.0,浏览器打开192.168.1.1
登录天翼智能网关web页面进去看配置,翻了个底朝天也没发现DNS配置在哪,我记得这里是可以配置DNS的啊(怀疑人生中…),上知乎搜了一圈发现有些老哥在喷电信说3.0版本不能修改DNS配置了(存疑,姑且信了…)。
但是还是要确认是DNS服务器的原因,怎么办呢?很简单,既然网关找不到配置,那就上网搜索一下深圳电信这个片区的DNS服务器地址是多少,然后指明这个服务器地址再测试一下即可。
Query Specific Name Server
从中国广东电信DNS服务器IP地址查到深圳电信的DNS服务器地址为202.96.134.133
,接下来指明server参数测试:
nslookup命令
1 2 3 4 5 6
| $ nslookup cdnjs.cloudflare.com 202.96.134.133 Server: 202.96.134.133 Address: 202.96.134.133
Name: cdnjs.cloudflare.com Address: 127.0.0.1
|
dig命令(注意dig的server参数要加上@
,很容易忘掉然后错误地用/etc/resolv.conf
里面的默认server去查两个记录了)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| $ dig cdnjs.cloudflare.com @202.96.134.133
; <<>> DiG 9.10.6 <<>> cdnjs.cloudflare.com @202.96.134.133 ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 62035 ;; flags: qr aa rd; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0 ;; WARNING: recursion requested but not available
;; QUESTION SECTION: ;cdnjs.cloudflare.com. IN A
;; ANSWER SECTION: cdnjs.cloudflare.com. 300 IN A 127.0.0.1
;; Query time: 8 msec ;; SERVER: 202.96.134.133#53(202.96.134.133) ;; WHEN: Mon Jul 04 20:09:52 CST 2022 ;; MSG SIZE rcvd: 54
|
🪨🔨🌶️,铁证如山呐,深圳电信DNS把cdnjs.cloudflare.com
解析到了127.0.0.1
。
做个对比,测了一下老家安徽电信的DNS(61.132.163.68
)和公共的阿里云DNS(223.5.5.5
),解析结果如下
1 2 3 4 5 6 7 8 9
| $ nslookup cdnjs.cloudflare.com 61.132.163.68 Server: 61.132.163.68 Address: 61.132.163.68
Non-authoritative answer: Name: cdnjs.cloudflare.com Address: 104.17.25.14 Name: cdnjs.cloudflare.com Address: 104.17.24.14
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| $ dig cdnjs.cloudflare.com @223.5.5.5
; <<>> DiG 9.10.6 <<>> cdnjs.cloudflare.com @223.5.5.5 ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 7837 ;; flags: qr rd ra; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 0
;; QUESTION SECTION: ;cdnjs.cloudflare.com. IN A
;; ANSWER SECTION: cdnjs.cloudflare.com. 98 IN A 104.17.25.14 cdnjs.cloudflare.com. 98 IN A 104.17.24.14
;; Query time: 9 msec ;; SERVER: 223.5.5.5#53(223.5.5.5) ;; WHEN: Mon Jul 04 20:10:15 CST 2022 ;; MSG SIZE rcvd: 70
|
可见安徽电信和阿里云的DNS均可以正确解析出ip为104.17.24.14
和104.17.25.14
👍
解决办法🔧
换成国内CDN
昨晚的第一反应是把cloudflare CDN换成国内的bootCDN,见Github Commit - Line 13
如果用户主要是国外的那另说,其实国内用还是优先上国内的CDN,速度上确实快不少,而且相对来说稳定性也好一点。我每次偷懒直接从官方文档里面复制粘贴CDN地址就没管过前端代码了😓。
附国内常见的CDN:
修改hosts
上面用公共DNS server已经查到对应的ip地址了,直接在hosts中把cdnjs.cloudflare.com
解析到104.17.24.14
,hosts里面配置的优先级高于一般走的DNS解析流程,肯定可以解决问题。
sudo vi /etc/hosts
添加下面这一行
104.17.24.14 cdnjs.cloudflare.com
即可
修改DNS server
修改hosts是改动最小的做法,但是如果未来还有别的网址解析失败就很麻烦了,不好维护。所以更方便的做法改DNS server,而且最好是改网关的DNS server(前文已经说了,天翼网关3.0貌似改不了),那只能退而求其次改本机的了。
一般来说越近的DNS server越快,所以运营商的是最快的(架不住运营商有时候干点恶心人的事情),再慢一点就是国内公共DNS,最慢的是国外的。于是找了几个公共DNS server出来ping了一下,比如阿里、腾讯、百度、114、谷歌的,发现延迟最小的是阿里云的223.5.5.5
。
删掉hosts里面的记录然后把本机器的DNS server改成223.5.5.5
,也能解决问题。
经验总结📖
- 主体目标用户在国内的话用国内CDN;
- DNS server最好配置成公共DNS;
有待进一步了解🎯
参考💼