Atingir exaustão de porta TCP efêmera

1

Executamos um site de alto tráfego. Nos últimos dias, vários clientes reclamaram de períodos de inatividade esporádicos que não conseguimos reproduzir. Temos vários servidores da Web eleitos para receber tráfego de nosso balanceador de carga e, ao investigar, percebi que todos os servidores estavam soltando mais de 20 conexões por segundo. Uma amostra de conexões de um servidor ficou assim:

  38452 TIME_WAIT
   7815 ESTABLISHED
    570 FIN_WAIT2
    105 FIN_WAIT1
    101 LAST_ACK
     36 SYN_RECV
     25 CLOSING
      4 SYN_SENT
      2 CLOSE_WAIT
      1 Foreign

Nosso intervalo de portas configurado está atualmente definido como 15000 61000 em todos os servidores. Parece, então, que todas as portas possíveis devem estar se esgotando, já que o número de conexões estabelecidas ou esperando para fechar é igual a 46267.

Enquanto investigamos o tráfego, o que devemos fazer com relação às conexões descartadas? Pode ser sensato aumentar nosso alcance de portas? Diminuir a quantidade de tempo que as conexões de fechamento aguardam? Ambos? Teria algum efeito potencialmente negativo?

    
por EricR 17.01.2015 / 04:38

1 resposta

1

Existem algumas maneiras de lidar com essa.

A maneira mais fácil é aumentar o alcance efêmero, mas você já meio que fez isso e obviamente há limites até onde você pode ir com essa solução.

Outra solução seria o DNS round-robin e a adição de vários endereços IP aos nós do balanceador de carga. Às vezes isso não é facilmente aplicável (você precisa esperar para obter IPs adicionais, aguardar o período de propagação do DNS, etc.).

Duas coisas que você pode fazer com segurança imediatamente, enquanto considera outras soluções de longo prazo, seriam diminuir os timers TCP e ativar tcp_reuse.

tcp_reuse é bastante seguro de usar no balanceador de carga, e o que ele faz é permitir que o kernel reutilize sockets no estado TIME_WAIT para novas conexões. Para ligá-lo, corra na sua caixa linux:

# sysctl -w net.ipv4.tcp_tw_reuse=1

Para tornar a inicialização persistente:

# echo "net.ipv4.tcp_tw_reuse = 1" >> /etc/sysctl.d/net.ipv4.tcp_tw_reuse.conf

Outros parâmetros de ajuste do kernel que podem ajudar são:

  • net.core.somaxconn (tamanho da fila de escuta)
  • net.ipv4.tcp_max_syn_backlog (número de solicitações de conexão lembradas sem o ACK)

Além disso, você pode diminuir o net.ipv4.tcp_fin_timeout para 1 ou 2 (quanto tempo manter os sockets no estado FIN-WAIT-2 se o seu host for a única conexão de fechamento).

Espero que ajude.

    
por 17.01.2015 / 15:20