Normalmente, balanceadores de carga como os Elastic Load Balancers da Amazon usam um conjunto de registros DNS com vários registros A para fornecer várias instâncias de balanceadores de carga que podem lidar com o tráfego para endpoints solicitantes:
$ dig +short my-fancy-elb.us-east-1.elb.amazonaws.com
10.0.1.1
10.0.1.2
Se eu tentar enrolar este URL no modo detalhado, noto que curl
parece tentativas de round-robin para os dois endereços 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)
O fato de curl
fazer round-robin nos registros A descritos no conjunto de registros é feito pelo curl
próprio binário ou é algo que o kernel do Linux faz por ele?
O TCP existe na camada 4 e o DNS existe na camada 7, então imagino que os binários e bibliotecas individuais teriam que implementar seu próprio balanceamento de carga e failover: buscar o conjunto de registros DNS para o nome de domínio fornecido e escolher um endereço TCP para conectar a partir desse conjunto.
Posso razoavelmente esperar que linguagens de programação, navegadores e bibliotecas como curl façam balanceamento de carga e failover em registros A para mim?
A resposta curta é que varia.
Quando vários registros de endereço estão presentes no conjunto de respostas, um servidor DNS consultado normalmente os retorna em uma ordem aleatória. O sistema operacional normalmente apresentará o conjunto de registros retornado ao aplicativo na ordem em que foram recebidos. Dito isso, existem opções em ambos os lados da transação (o servidor de nomes e o sistema operacional) que podem resultar em comportamentos diferentes. Geralmente estes não são empregados. Por exemplo, um arquivo pouco conhecido chamado
/etc/gai.conf
controla isso em sistemas baseados em glibc.O livro Zytrax (DNS for Rocket Scientists) tem um bom resumo sobre a história deste tópico e conclui que o RFC 6724 é o padrão atual ao qual os aplicativos e as implementações de resolvedor devem aderir.
A partir daqui, vale a pena observar uma citação de escolha da RFC 6724:
O padrão incentiva os aplicativos a não pararem no primeiro endereço em caso de falha, mas não é um requisito nem o comportamento que muitos aplicativos escritos casualmente irão implementar. Você nunca deve confiar apenas em vários registros de endereço para alta disponibilidade, a menos que tenha certeza de que a porcentagem maior (ou pelo menos a mais importante) de seus aplicativos de consumo funcionará bem. Os navegadores modernos tendem a ser bons quanto a isso, mas lembre-se de que eles não são os únicos consumidores com os quais você está lidando.
(além disso, como @kasperd observa abaixo, é importante distinguir entre o que isso traz para você em HA versus balanceamento de carga)
Meu palpite é que o DNS TTL para o registro está muito baixo e
curl
só precisa ser resolvido novamente todas as vezes e obterá outro IP do servidor DNS.Nem
curl
o kernel estão cientes de que esse balanceamento de carga no nível de DNS acontece e você não pode esperar algo assim.O básico é que os servidores DNS geralmente alternam os registros de maneira pseudo-aleatória.
No caso do curl, ele possui sua própria biblioteca de resolução de DNS que respeita a ordem de apresentação do servidor.
Há uma história sobre este tópico em https://daniel.haxx.se/blog/2012/01/03/getaddrinfo-with-round-robin-dns-and-happy-eyeballs/ . A implementação do curl também é mencionada lá.
Nenhum. É o servidor DNS que normalmente altera o endereço IP. A biblioteca curl precisa resolver o nome do host para obter o endereço IP de cada solicitação. Ele envia a solicitação ao servidor DNS, que envia de volta uma lista de endereços IP. O servidor DNS também pode ser local na mesma máquina para armazenamento em cache. A maior parte do servidor DNS gira o round-robin da lista de IP em cada solicitação. Assim, você obtém um IP diferente em cada solicitação, pois o IP superior da lista foi alterado. Se você executar ping em www.google.com a partir de uma máquina Linux, provavelmente verá um endereço diferente a cada vez.
Realizei um teste com curl para buscar um arquivo em http. Curl é capaz de tentar novamente com outro IP quando o primeiro ip não está acessível (failover). Então, 'failover' está trabalhando com curl para solicitação http.