O que limita o número máximo de conexões em um servidor Linux?

86

Qual parâmetro do kernel ou outras configurações controlam o número máximo de soquetes TCP que podem ser abertos em um servidor Linux? Quais são as vantagens de permitir mais conexões?

Eu notei durante o teste de carga de um servidor Apache com ab que é muito fácil maximizar as conexões abertas no servidor. Se você deixar a opção ab -k, que permite a reutilização da conexão, e enviar mais de 10.000 solicitações, o Apache atende as primeiras 11.000 solicitações e, em seguida, pára por 60 segundos. Uma olhada na saída do netstat mostra 11.000 conexões no estado TIME_WAIT. Aparentemente, isso é normal. As conexões são mantidas abertas um padrão de 60 segundos, mesmo após o término do cliente para motivos de confiabilidade TCP .

Parece que essa seria uma maneira fácil de fazer DoS um servidor e estou me perguntando quais são as afinações e precauções habituais para ele.

Aqui está minha saída de teste:

# ab -c 5 -n 50000 http://localhost/
This is ApacheBench, Version 2.0.40-dev <$Revision: 1.146 $> apache-2.0
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Copyright 2006 The Apache Software Foundation, http://www.apache.org/

Benchmarking localhost (be patient)
Completed 5000 requests
Completed 10000 requests
apr_poll: The timeout specified has expired (70007)
Total of 11655 requests completed

Aqui está o comando netstat que eu corri durante o teste:

 # netstat --inet -p | grep "localhost:www" | sed -e 's/ \+/ /g' | cut -d' ' -f 1-4,6-7 | sort | uniq -c 
  11651 tcp 0 0 localhost:www TIME_WAIT -
      1 tcp 0 1 localhost:44423 SYN_SENT 7831/ab
      1 tcp 0 1 localhost:44424 SYN_SENT 7831/ab
      1 tcp 0 1 localhost:44425 SYN_SENT 7831/ab
      1 tcp 0 1 localhost:44426 SYN_SENT 7831/ab
      1 tcp 0 1 localhost:44428 SYN_SENT 7831/ab
    
por Ben Williams 21.05.2009 / 16:18

8 respostas

62

Eu finalmente encontrei a configuração que realmente limitava o número de conexões: net.ipv4.netfilter.ip_conntrack_max . Isso foi definido como 11.776 e o que eu configurei é o número de solicitações que posso atender no meu teste antes de ter que esperar tcp_fin_timeout segundos para que mais conexões fiquem disponíveis. A tabela conntrack é o que o kernel usa para rastrear o estado das conexões. Assim, quando estiver cheio, o kernel começa a eliminar pacotes e a imprimi-lo no log:

Jun  2 20:39:14 XXXX-XXX kernel: ip_conntrack: table full, dropping packet.

A próxima etapa foi fazer com que o kernel reciclasse todas essas conexões no estado TIME_WAIT em vez de descartar pacotes. Eu poderia fazer isso acontecer ativando tcp_tw_recycle ou aumentando ip_conntrack_max para ser maior que o número de portas locais disponibilizadas para conexões por ip_local_port_range . Eu acho que uma vez que o kernel está fora de portas locais, ele começa a reciclar conexões. Isso usa mais conexões de rastreamento de memória, mas parece ser a melhor solução do que ativar tcp_tw_recycle , já que os documentos implicam que isso é perigoso.

Com essa configuração, posso executar o dia todo ab e nunca ficar sem conexões:

net.ipv4.netfilter.ip_conntrack_max = 32768
net.ipv4.tcp_tw_recycle = 0
net.ipv4.tcp_tw_reuse = 0
net.ipv4.tcp_orphan_retries = 1
net.ipv4.tcp_fin_timeout = 25
net.ipv4.tcp_max_orphans = 8192
net.ipv4.ip_local_port_range = 32768    61000

A configuração tcp_max_orphans não teve nenhum efeito nos meus testes e não sei por quê. Eu acho que seria fechar as conexões em TIME_WAIT state, uma vez que havia 8192 deles, mas isso não faz isso para mim.

    
por 03.06.2009 / 16:02
23

Você realmente quer ver o que o sistema de arquivos / proc tem a lhe oferecer nesse sentido.

Na última página, você pode encontrar o seguinte para ser de seu interesse:

  • / proc / sys / net / ipv4 / tcp_max_orphans , que controla o número máximo de soquetes mantidos pelo sistema não anexado a algo. Aumentar isso pode consumir até 64kbyte de memória não-swappable por socket órfão .
  • / proc / sys / net / ipv4 / tcp_orphan_retries , que controla a quantidade de novas tentativas antes que um soquete fique órfão e fechado. Há uma observação específica nessa página sobre servidores da web que é de interesse direto para você ...
por 21.05.2009 / 18:15
3

Eu não acho que haja um ajuste para definir isso diretamente. Isso se enquadra na categoria de ajuste TCP / IP. Para descobrir o que você pode ajustar, tente 'man 7 tcp'. O sysctl ('man 8 sysctl') é usado para configurá-los. 'sysctl -a | grep tcp 'mostrará a você a maior parte do que você pode ajustar, mas não tenho certeza se mostrará todas elas. Além disso, a menos que isso tenha mudado, os soquetes TCP / IP se abrem como descritores de arquivos. Então isso e a próxima seção desse link pode ser o que você está procurando.

    
por 21.05.2009 / 17:31
2

Tente definir também o seguinte, definindo tcp_fin_timeout. Isso deve fechar TIME_WAIT mais rapidamente.

net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_tw_recycle = 1
    
por 21.05.2009 / 19:38
2

O estoque do apache (1) costumava vir predefinido para suportar apenas 250 conexões simultâneas - se você quisesse mais, havia um arquivo de cabeçalho para modificar para permitir sessões mais simultâneas. Não sei se isso ainda é verdade com o Apache 2.

Além disso, você precisa adicionar uma opção para permitir cargas de mais descritores de arquivos abertos para a conta que executa o Apache - algo que os comentários anteriores não apontam.

Preste atenção às suas configurações de trabalho e que tipo de tempos limite de keepalive você tem dentro do próprio Apache, quantos servidores de reserva você tem em execução de uma vez e quão rápido esses processos extras estão sendo mortos.

    
por 21.05.2009 / 21:21
1

Você pode reduzir o tempo gasto no estado TIME_WAIT (Definir net.ipv4.tcp_fin_timeout). Você poderia substituir o Apache por YAWS ou nginx ou algo similar.

Trocas de mais conexões geralmente envolvem o uso de memória, e se você tiver um processo de bifurcação, muitos processos filhos afetam sua CPU.

    
por 21.05.2009 / 16:26
0

O número absoluto de soquetes que podem ser abertos em um único endereço IP é 2 ^ 16 e é definido por TCP / UDP, não pelo kernel.

    
por 30.05.2009 / 16:42
0

A ferramenta de benchmarking do servidor HTTP Apache, ab , na versão 2.4 tem o . Consulte também erro do ab (Apache Bench): apr_poll: O tempo limite especificado expirou (70007) no Windows .

Esta opção resolve seu problema.

    
por 08.02.2013 / 17:56