我们知道google有多个IP地址。如果我们使用网站https://toolbox.googleapps.com/apps/dig/#A/google.com@8.8.8.8,它会产生多个谷歌的IP地址。
如果我运行以下命令,那么情况就不同了:
gyan@localhost:~/codes/java/net$ dig google.com
; <<>> DiG 9.10.3-P4-Ubuntu <<>> google.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 11777
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4000
;; QUESTION SECTION:
;google.com. IN A
;; ANSWER SECTION:
google.com. 269 IN A 216.58.220.46
;; Query time: 0 msec
;; SERVER: 10.100.171.1#53(10.100.171.1)
;; WHEN: Fri Nov 04 16:18:07 IST 2016
;; MSG SIZE rcvd: 55
gyan@localhost:~/codes/java/net$
只返回一个IP地址,与上述网站返回的IP地址不相同。该IP地址也在不断变化。
但是如果我在amazon.com上运行dig命令:
gyan@localhost:~/codes/java/net$ dig amazon.com
; <<>> DiG 9.10.3-P4-Ubuntu <<>> amazon.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 55090
;; flags: qr rd ra; QUERY: 1, ANSWER: 6, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4000
;; QUESTION SECTION:
;amazon.com. IN A
;; ANSWER SECTION:
amazon.com. 34 IN A 54.239.26.128
amazon.com. 34 IN A 54.239.17.7
amazon.com. 34 IN A 54.239.25.192
amazon.com. 34 IN A 54.239.25.208
amazon.com. 34 IN A 54.239.25.200
amazon.com. 34 IN A 54.239.17.6
;; Query time: 74 msec
;; SERVER: 127.0.1.1#53(127.0.1.1)
;; WHEN: Fri Nov 04 16:23:17 IST 2016
;; MSG SIZE rcvd: 135
gyan@localhost:~/codes/java/net$
这6个IP地址永远不会改变。网站https://toolbox.googleapps.com/apps/dig/#A/amazon.com@8.8.8.8也返回相同的6个IP地址。
我的疑问是DNS查找google.com和amazon.com有什么不同?为什么google只显示一条记录,而不是像amazon那样显示多条记录?
我们知道google有不止一个IP地址。
正确的。但这并不意味着客户需要知道不止一个。
在过去,为了执行负载平衡,服务使用多个IP地址响应DNS查询是非常常见的。应答通常是随机的,这意味着客户端将从所有行为相同的大型服务器地址池中获得几个地址的随机子集。
基于DNS的负载均衡一直是一个黑客。由于缓存,它会出现问题:如果ISP的DNS解析器缓存应答,那么大量用户都会连接到这几个IP地址,从而降低负载平衡的有效性。解决这个问题的方法是降低记录的TTL,以确保条目在缓存中停留一小段时间,之后执行一个新的查询。例如,在您发布的dig输出中,对于amazon.com A记录,TTL设置为34秒。
这个方法不是很有效。减少TTL会进一步增加小型HTTP请求的延迟。此外,DNS负载平衡的结果有点不可预测,因为它不能保证服务器将均匀地处理负载。
但是,如果你有一个在网络级别工作的负载均衡器(把它想象成一个反向NAT盒子:一个IP面向互联网,将流量复用到它后面的大量服务器),可以处理大量连接,并且也有很好的正常运行时间,那么就没有必要在DNS级别做负载平衡。
所以很可能你连接的谷歌数据中心不使用DNS负载平衡,而亚马逊的数据中心使用。
另一个问题是为什么如果你从工具箱中查询8.8.8.8,你会得到多个地址,而从你的机器中查询,你只得到一个。
首先,重要的是要明白,当从工具箱中查询时,是web服务器发送DNS查询,而不是您的计算机。
DNS服务器不必向不同的客户端返回相同的应答。实际上,根据客户端的地理位置返回不同的答复是很常见的:例如,如果欧洲的用户查询google.com,它将得到欧洲数据中心的IP地址,而不是美国。
在这种情况下,我认为DNS地理位置用于某些客户端,而不是用于其他客户端。这可能与发送查询的网络的大小以及网络负载平衡器的容量有关。例如,如果负载均衡器可以同时处理1,000,000个连接,而您发送查询的网络有100,000个ip,则不需要进行DNS负载平衡。但是,如果网络很大(在您的示例中,运行工具箱的数据中心的大小),网络负载平衡器可能无法处理它,因此启用DNS负载平衡,您可以从池中获得多个随机IP地址。
注意:这里的"网络"是指使用相同DNS解析器的一组机器。
返回多个IP地址的另一个原因是执行基于dns的故障转移。当其中一台机器停止工作时,客户端尝试连接到另一台机器。但这并不是一种很好的故障转移方式,因为有些应用程序不存储所有的IP地址(尽管我认为大多数浏览器都这样做),而且DNS缓存也会碍事。