通常,负载平衡器(如Amazon的弹性负载平衡器)使用包含多个Alogging的DNSlogging集来提供多个负载平衡器实例,这些实例可以处理到请求端点的stream量:
$ dig +short my-fancy-elb.us-east-1.elb.amazonaws.com 10.0.1.1 10.0.1.2
如果我试图在详细模式下curl这个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)
curl是否对curl二进制文件logging集中描述的Alogging进行循环,或者是Linux内核为它做了什么?
TCP存在于第4层,DNS存在于第7层,所以我可以想象,单独的二进制文件和库将不得不实现自己的负载平衡和故障转移:获取给定域名的DNSlogging集,并selectTCP地址连接到该设置。
我可以合理地期望像curl这样的编程语言,浏览器和类库会为Alogging进行负载平衡和故障转移吗?
简单的答案是它有所不同。
当答案集中存在多个地址logging时,查询的DNS服务器通常以随机顺序返回它们。 操作系统通常会按照收到的顺序将返回的logging集呈现给应用程序。 也就是说,在事务(名称服务器和操作系统)的两端都有可能导致不同行为的选项。 通常这些不被雇用。 例如,一个名为/etc/gai.conf的鲜为人知的文件在基于glibc的系统上控制这个文件。
Zytrax的书(火箭科学家的DNS) 对这个主题的历史有一个很好的总结 ,并且认为RFC 6724是当前应用程序和parsing器实现应遵守的标准。
从这里值得注意的是RFC 6724的select引用 :
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 (eg, with some small delay in between) and use the first one to succeed.
这个标准鼓励应用程序不要停在第一个失败的地址,但它既不是要求,也不是许多随意编写的应用程序要实现的行为。 除非您确定消费应用程序的更大(或至less是最重要的)百分比可以很好地发挥作用,否则绝不应单纯依靠多个地址logging来实现高可用性。 现代浏览器往往是好的,但请记住,他们不是你正在处理的唯一的消费者。
(同样,下面的@kasperd注释,区分这在HA中购买你与负载平衡是很重要的)
我猜测会发生什么事是logging的DNS TTL设置得非常低, curl每次都需要再次parsing,并且会从DNS服务器获得另一个IP。
curl和内核都不知道这个DNS级别的负载平衡发生,你不能合理地期待这样的事情。
基本的东西是DNS服务器通常以伪随机方式循环logging。
fedor@piecka:~$ dig +short @ns1.yahoo.com yahoo.com 206.190.36.45 98.138.253.109 98.139.183.24 fedor@piecka:~$ dig +short @ns1.yahoo.com yahoo.com 98.139.183.24 206.190.36.45 98.138.253.109 fedor@piecka:~$ dig +short @ns1.yahoo.com yahoo.com 98.139.183.24 98.138.253.109 206.190.36.45
在curl的情况下,它有它自己的DNSparsing库,它尊重服务器呈现的顺序。
在https://daniel.haxx.se/blog/2012/01/03/getaddrinfo-with-round-robin-dns-and-happy-eyeballs/上有一个关于这个话题的故事。 那里也提到了curl的实现。
curl是否对curl二进制文件logging集中描述的Alogging进行循环,或者是Linux内核为它做了什么?
都不是。 它通常是改变IP地址的DNS服务器。 curl库需要parsing主机名来获取每个请求的IP地址。 它将请求发送到发送回IP地址列表的DNS服务器。 DNS服务器也可以在同一台机器上进行本地caching。 大多数DNS服务器在每个请求中循环轮询IP列表。 因此,您在每个请求中获得不同的IP,因为列表的顶端IP已更改。 如果您从Linux机器上ping http://www.google.com,则每次都会看到不同的地址。
客户通常是否在多个Alogging上实现故障转移/负载平衡?
我用curl执行了一个testing,通过http获取文件。 当第一个IP不可访问(故障转移)时,Curl能够用另一个IP重试。 因此,“故障转移”正在与curl处理http请求。