Naf*_*Kay 7 domain-name-system tcp
通常,像 Amazon 的 Elastic Load Balancers 这样的负载均衡器使用具有多个 A 记录的 DNS 记录集来提供多个负载均衡器实例,这些实例可以处理到请求端点的流量:
$ dig +short my-fancy-elb.us-east-1.elb.amazonaws.com
10.0.1.1
10.0.1.2
Run Code Online (Sandbox Code Playgroud)
如果我尝试以详细模式卷曲此 URL,我会注意到curl
似乎对两个 IP 地址进行循环尝试:
$ curl -ivs http://my-fancy-elb.us-east-1.elb.amazonaws.com | grep -i 'connected'
* Connected to my-fancy-elb.us-east-1.elb.amazonaws.com (10.0.1.1)
$ curl -ivs http://my-fancy-elb.us-east-1.elb.amazonaws.com | grep -i 'connected'
* Connected to my-fancy-elb.us-east-1.elb.amazonaws.com (10.0.1.2)
Run Code Online (Sandbox Code Playgroud)
curl
对记录集中描述的 A 记录进行循环的事实是由curl
二进制本身完成的还是 Linux 内核为它做的?
TCP 存在于第 4 层,DNS 存在于第 7 层,所以我想各个二进制文件和库必须实现自己的负载平衡和故障转移:获取给定域名的 DNS 记录集并选择一个 TCP 地址以从那个集合连接到。
我可以合理地期望编程语言、浏览器和像 curl 这样的库会为我在 A 记录上进行负载平衡和故障转移吗?
And*_*w B 10
简短的回答是它会有所不同。
当答案集中存在多个地址记录时,被查询的 DNS 服务器通常以随机顺序返回它们。操作系统通常会按照接收到的顺序将返回的记录集呈现给应用程序。也就是说,事务的双方(名称服务器和操作系统)都有可能导致不同行为的选项。通常不使用这些。例如,/etc/gai.conf
在基于 glibc 的系统上,一个鲜为人知的名为控制此的文件。
Zytrax 一书(火箭科学家的 DNS)对该主题的历史进行了很好的总结,并得出结论认为RFC 6724是应用程序和解析器实现应遵守的当前标准。
从这里值得注意的是来自 RFC 6724的选择引用:
Well-behaved applications SHOULD NOT simply use the first address
returned from an API such as getaddrinfo() and then give up if it
fails. For many applications, it is appropriate to iterate through
the list of addresses returned from getaddrinfo() until a working
address is found. For other applications, it might be appropriate to
try multiple addresses in parallel (e.g., with some small delay in
between) and use the first one to succeed.
Run Code Online (Sandbox Code Playgroud)
该标准鼓励应用程序在失败时不要停在第一个地址,但这不是许多随意编写的应用程序将要实现的要求或行为。您永远不应该仅仅依赖多个地址记录来实现高可用性,除非您确定更大(或至少是最重要的)使用应用程序的百分比会很好地运行。现代浏览器往往在这方面做得很好,但请记住,他们并不是您要处理的唯一消费者。
(此外,正如@kasperd 在下面指出的,重要的是要区分这在 HA 和负载平衡中为您带来的好处)