Por que meu servidor da Web está cortando conexões com uma redefinição de TCP em alta carga?

10

Eu tenho uma pequena instalação VPS com nginx. Quero extrair o máximo de desempenho possível, por isso tenho experimentado otimização e teste de carga.

Estou usando o Blitz.io para fazer o teste de carga, obtendo um pequeno arquivo de texto estático e encontrando um problema estranho em que o servidor parece estar enviando redefinições de TCP quando o número de conexões simultâneas atingir aproximadamente 2000. Eu sei que isso é muito grande quantidade, mas, ao usar o htop, o servidor ainda tem muito tempo de sobra na memória e no tempo da CPU, portanto, gostaria de descobrir a fonte desse problema para ver se consigo avançar ainda mais.

Estou executando o Ubuntu 14.04 LTS (64 bits) em um VPS Linode de 2 GB.

Não tenho reputação suficiente para postar este gráfico diretamente, então aqui está um link para o gráfico Blitz.io:

insira a descrição da imagem aqui

Aqui estão algumas coisas que eu fiz para tentar descobrir a fonte do problema:

  • O valor de configuração do nginx worker_rlimit_nofileestá definido como 8192
  • ter nofiledefinido para 64000 para ambos os limites duros e macios para roote www-datausuário (o que nginx é executado como) em/etc/security/limits.conf
  • não há indicações de que algo esteja errado /var/log/nginx.d/error.log(normalmente, se você estiver executando os limites do descritor de arquivo, o nginx imprimirá mensagens de erro dizendo isso)

  • Eu tenho configuração ufw, mas não há regras de limitação de taxa. O log do ufw indica que nada está sendo bloqueado e tentei desabilitar o ufw com o mesmo resultado.

  • Não há erros indicativos no /var/log/kern.log
  • Não há erros indicativos no /var/log/syslog
  • Eu adicionei os seguintes valores /etc/sysctl.confe os carreguei sysctl -psem efeito:

    net.ipv4.tcp_max_syn_backlog = 1024
    net.core.somaxconn = 1024
    net.core.netdev_max_backlog = 2000
    

Alguma ideia?

EDIT: Eu fiz um novo teste, aumentando para 3000 conexões em um arquivo muito pequeno (apenas 3 bytes). Aqui está o gráfico Blitz.io:

Gráfico Blitz.io

Novamente, de acordo com Blitz, todos esses erros são erros de "redefinição de conexão TCP".

Aqui está o gráfico da largura de banda Linode. Lembre-se de que essa é uma média de 5 minutos, por isso a filtragem passa-baixa um pouco (a largura de banda instantânea provavelmente é muito maior), mas ainda assim, isso não é nada:

insira a descrição da imagem aqui

CPU:

insira a descrição da imagem aqui

E / S:

insira a descrição da imagem aqui

Aqui está htopperto do final do teste: htop

Também capturei parte do tráfego usando o tcpdump em um teste diferente (mas com aparência semelhante), iniciando a captura quando os erros começaram a aparecer: sudo tcpdump -nSi eth0 -w /tmp/loadtest.pcap -s0 port 80

Aqui está o arquivo, se alguém quiser dar uma olhada nele (~ 20 MB): https://drive.google.com/file/d/0B1NXWZBKQN6ETmg2SEFOZUsxV28/view?usp=sharing

Aqui está um gráfico de largura de banda do Wireshark:

insira a descrição da imagem aqui (Linha é todos os pacotes, barras azuis são erros de TCP)

Pela minha interpretação da captura (e não sou especialista), parece que os sinalizadores TCP RST são provenientes da fonte de teste de carga, não do servidor. Portanto, supondo que algo não esteja errado do lado do serviço de teste de carga, é seguro assumir que esse é o resultado de algum tipo de gerenciamento de rede ou atenuação do DDOS entre o serviço de teste de carga e o meu servidor?

Obrigado!

Erik Swan
fonte
O seu provedor está realizando algum tipo de mitigação de DDoS? Isso pode interferir no seu teste.
Michael Hampton
@ MichaelHampton Estou bastante certo de que Linode não faz isso.
EEAA
Você pode postar o gráfico de rede no painel de controle Linode? Quanta largura de banda este teste está realmente ocupando?
EEAA
Pesquisei um pouco mais e atualizei o post original com muito mais informações. Também confirmei com o Linode que eles não atenuam o DDOS, embora isso não signifique necessariamente que um provedor de rede entre o serviço de teste de carga e o Linode não esteja fazendo nada. Obrigado!
Swan
1
Existe uma razão para você configurar apenas net.core.netdev_max_backlog2000? Vários exemplos que eu já vi têm uma ordem de magnitude maior para conexões gigabit (e 10Gig).
Moshe Katz

Respostas:

1

Pode haver qualquer número de fontes das redefinições de conexão. O testador de carga pode estar fora das portas efêmeras disponíveis para iniciar uma conexão; um dispositivo ao longo do caminho (como um firewall executando NAT) pode ter seu pool de NAT esgotado e não pode fornecer uma porta de origem para a conexão. um balanceador de carga ou firewall no seu final que pode ter atingido um limite de conexão? E se estiver fazendo NAT de origem no tráfego de entrada, isso também poderá sofrer exaustão de porta.

Seria realmente necessário um arquivo pcap de ambas as extremidades. O que você deseja procurar é se uma tentativa de conexão for enviada, mas nunca chegar ao servidor, mas ainda aparecer como se tivesse sido redefinida pelo servidor. Se for esse o caso, algo na linha teve que redefinir a conexão. A exaustão do pool de NAT é uma fonte comum desses tipos de problemas.

Além disso, o netstat -st pode fornecer algumas informações adicionais.

GeorgeB
fonte
1

Algumas idéias para tentar, com base em minhas próprias experiências recentes de afinação semelhantes. Com referências:

Você diz que é um arquivo de texto estático. Caso ocorra algum processamento upstream, aparentemente os soquetes de domínio melhoram a taxa de transferência TCP através de uma conexão baseada na porta TC:

https://rtcamp.com/tutorials/php/fpm-sysctl-tweaking/ https://engineering.gosquared.com/optimising-nginx-node-js-and-networking-for-heavy-workloads

Independentemente da rescisão a montante:

Ative multi_accept e tcp_nodelay: http://tweaked.io/guide/nginx/

Desative o TCP Slow Start: /programming/17015611/disable-tcp-slow-start http://www.cdnplanet.com/blog/tune-tcp-initcwnd-for-optimum-performance/

Janela Otimizar o congestionamento de TCP (initcwnd): http://www.nateware.com/linux-network-tuning-for-2013.html

JayMcTee
fonte
1

Para definir o número máximo de arquivos abertos (se isso estiver causando seu problema), você precisa adicionar "fs.file-max = 64000" ao /etc/sysctl.conf

Sean1e
fonte
0

Observe quantas portas estão no TIME_WAITestado usando o comando netstat -patunl| grep TIME | wc -le mude net.ipv4.tcp_tw_reusepara 1.

fgbreel
fonte
Como eu olharia quantas portas existem no TIME_WAITestado?
Erik Swan
Usando netstatou ss. Eu atualizei minha resposta com o comando completo!
Fgbreel 01/04
Executei novamente o teste e watch -n 1 'sudo netstat -patunl | grep TIME | wc -l'retornou 0 ao longo de todo o teste. Estou certo de que as redefinições estão chegando como resultado da atenuação do DDOS por alguém entre o testador de carga e o meu servidor, com base na minha análise do arquivo PCAP que publiquei acima, mas se alguém puder confirmar isso seria ótimo!
Erik Swan