客户端通常是否对多个 A 记录实施故障转移/负载平衡?

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 和负载平衡中为您带来的好处)

  • 确实,不应依赖 DNS 响应中的多条记录作为唯一的负载平衡机制。DNS 可用于进行一些非常粗略的负载平衡。但是无论您在 DNS 层做什么,它都不会产生均匀的负载分布,因此您还需要在另一层进行负载平衡(或大量过剩容量)。即使您只有一个静态 A 记录,实际上也可以实现负载平衡,但我不推荐这种方法。 (3认同)
  • 但是,对于故障转移,您必须依靠客户端在不同地址之间实现故障转移。任何在客户端不依赖于此的解决方案都会在某处出现单点故障。但正如您所指出的,并非所有应用程序都表现良好。因此,需要努力使 DNS 分发的每个 IP 都可靠,即使由于 SPoF 对单个 IP 可实现的可靠性有限制。 (2认同)