Recentemente, tivemos um servidor apache que estava respondendo muito lentamente devido à inundação de SYN. A solução alternativa para isso foi ativar o tcp_syncookies ( net.ipv4.tcp_syncookies=1 in /etc/sysctl.conf
).
Eu postei uma pergunta sobre isso aqui, se você quiser mais informações.
Depois de ativar os sincookies, começamos a ver a seguinte mensagem em / var / log / messages aproximadamente a cada 60 segundos:
[84440.731929] possible SYN flooding on port 80. Sending cookies.
Vinko Vrsalovic me informou que isso significa que o backlog de sincronização está ficando cheio, então aumentei tcp_max_syn_backlog para 4096. Em algum momento, também reduzi tcp_synack_retries para 3 (abaixo do padrão de 5) ao emitir sysctl -w net.ipv4.tcp_synack_retries=3
. Depois disso, a frequência pareceu diminuir, com o intervalo das mensagens variando entre aproximadamente 60 e 180 segundos.
Em seguida, emiti sysctl -w net.ipv4.tcp_max_syn_backlog=65536
, mas ainda estou recebendo a mensagem no log.
Ao longo de tudo isso, observei o número de conexões no estado SYN_RECV (executando watch --interval=5 'netstat -tuna |grep "SYN_RECV"|wc -l'
), e ele nunca ultrapassa os 240, muito muito menor que o tamanho da lista de pendências. No entanto, eu tenho um servidor Red Hat que fica em torno de 512 (o limite neste servidor é o padrão de 1024).
Existem outras configurações de TCP que limitariam o tamanho da lista de pendências ou estou latindo na árvore errada? O número de conexões SYN_RECV deve estar netstat -tuna
correlacionado com o tamanho da lista de pendências?
Atualizar
O melhor que posso dizer é que estou lidando com conexões legítimas aqui, netstat -tuna|wc -l
pairando em torno de 5000. Pesquisei isso hoje e encontrei esta postagem de um funcionário do last.fm, que foi bastante útil.
Também descobri que o tcp_max_syn_backlog não tem efeito quando os sincookies estão ativados (conforme este link )
Assim, na próxima etapa, defino o seguinte no sysctl.conf:
net.ipv4.tcp_syn_retries = 3
# default=5
net.ipv4.tcp_synack_retries = 3
# default=5
net.ipv4.tcp_max_syn_backlog = 65536
# default=1024
net.core.wmem_max = 8388608
# default=124928
net.core.rmem_max = 8388608
# default=131071
net.core.somaxconn = 512
# default = 128
net.core.optmem_max = 81920
# default = 20480
Em seguida, configurei meu teste de tempo de resposta, executei sysctl -p
e desativei as sincookies por sysctl -w net.ipv4.tcp_syncookies=0
.
Após fazer isso, o número de conexões no estado SYN_RECV ainda permanecia em torno de 220-250, mas as conexões estavam começando a atrasar novamente. Depois que notei esses atrasos, reativei as sincookies e os atrasos pararam.
Acredito que o que eu estava vendo ainda era uma melhoria em relação ao estado inicial, no entanto, alguns pedidos ainda estavam atrasados, o que é muito pior do que ter sincookies ativadas. Parece que estou preso a eles ativados até conseguirmos mais servidores online para lidar com a carga. Mesmo assim, não tenho certeza se vejo um motivo válido para desativá-los novamente, pois eles são enviados (aparentemente) apenas quando os buffers do servidor ficam cheios.
Mas o backlog syn não parece estar cheio com apenas ~ 250 conexões no estado SYN_RECV! É possível que a mensagem de inundação do SYN seja um arenque vermelho e algo diferente do syn_backlog que está sendo preenchido?
Se alguém tiver outras opções de ajuste, ainda não tentei, ficaria feliz em experimentá-las, mas estou começando a me perguntar se a configuração syn_backlog não está sendo aplicada corretamente por algum motivo.