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:
Aqui estão algumas coisas que eu fiz para tentar descobrir a fonte do problema:
- O valor de configuração do nginx
worker_rlimit_nofile
está definido como 8192 - ter
nofile
definido para 64000 para ambos os limites duros e macios pararoot
ewww-data
usuá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.conf
e os carregueisysctl -p
sem 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:
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:
CPU:
E / S:
Aqui está htop
perto do final do teste:
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:
(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!
net.core.netdev_max_backlog
2000? Vários exemplos que eu já vi têm uma ordem de magnitude maior para conexões gigabit (e 10Gig).Respostas:
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.
fonte
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
fonte
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
fonte
Observe quantas portas estão no
TIME_WAIT
estado usando o comandonetstat -patunl| grep TIME | wc -l
e mudenet.ipv4.tcp_tw_reuse
para 1.fonte
TIME_WAIT
estado?netstat
ouss
. Eu atualizei minha resposta com o comando completo!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!