Comecei a usar o Nginx como proxy reverso para um conjunto de servidores que fornecem algum tipo de serviço.
O serviço pode ser bastante lento às vezes (sua execução no Java e na JVM às vezes fica presa na "coleta de lixo completa" que pode levar vários segundos), então eu configurei o valor proxy_connect_timeout
para 2 segundos, o que dará ao Nginx tempo suficiente para descobrir se o serviço está parado no GC e não responde a tempo, deve passar a solicitação para um servidor diferente.
Também definai proxy_read_timeout
para impedir que o proxy reverso seja bloqueado se o serviço em si demorar muito para calcular a resposta - novamente, ele deve mover a solicitação para outro servidor que seja livre o suficiente para retornar uma resposta oportuna.
Eu executei alguns benchmarks e posso ver claramente que isso proxy_connect_timeout
funciona corretamente, pois algumas solicitações retornam exatamente no tempo especificado para o tempo limite da conexão, pois o serviço está parado e não aceita conexões de entrada (o serviço está usando o Jetty como um incorporado contêiner de servlet). O proxy_read_timeout
também funciona, como posso ver os pedidos que retornam após o tempo limite especificado lá.
O problema é que eu esperava ver algumas solicitações que atingissem o tempo limite após proxy_read_timeout + proxy_connect_timeout
, ou quase esse período, se o serviço estiver travado e não aceitar conexões quando o Nginx tentar acessá-lo, mas antes que o Nginx possa atingir o tempo limite - ele será liberado e inicia o processamento, mas é muito lento e o Nginx seria interrompido devido ao tempo limite da leitura. Acredito que o serviço tenha esses casos, mas depois de executar vários benchmarks, totalizando vários milhões de solicitações - não consegui ver uma única solicitação que retorne em qualquer coisa acima proxy_read_timeout
(que é o tempo limite maior).
Gostaria de receber qualquer comentário sobre esse problema, embora eu ache que isso possa ter ocorrido devido a um bug no Nginx (eu ainda não verifiquei o código, então isso é apenas uma suposição) de que o contador de tempo limite não é redefinido após a conexão for bem-sucedido, se o Nginx não leu nada do servidor upstream.
proxy_read_timeout
não é o "tempo limite global", mas entre duas operações de leitura.proxy_read_timeout + proxy_connect_timeout
.Respostas:
Na verdade, não consegui reproduzir isso em:
Eu configurei isso no meu nginx.conf:
Eu, então, configurei dois servidores de teste. Um que acabaria com o tempo limite no SYN e outro que aceitaria conexões, mas nunca responderia:
Então enviei uma conexão de teste:
Então assisti error_log que mostrava isso:
então:
E então o access.log que tem o tempo limite esperado de 30s (10 + 20):
Aqui está o formato de log que estou usando, que inclui os tempos limite de upstream individuais:
fonte
proxy_send_timeout
) e, como você a definiu para um valor mais altoproxy_connection_timeout
, isso pode ser responsável por qualquer atraso nos 20 segundosproxy_read_timeout
. Quando você diz "cuspir linhas muito lentamente" - o que você quer dizer?proxy_read_timeout
que a solicitação falhe completamente ou permita completamente. Isso também explica a diferença entre o comportamento que você vê e o que eu vejo.O tempo limite de conexão significa que o TCP para quando o handshake (por exemplo, não havia SYN_ACKs). O TCP tentaria novamente enviar SYNs, mas você deu apenas 2 segundos. para o Nginx usar outro servidor, portanto, simplesmente não há tempo para reenviar SYNs.
UPD. : Não foi possível encontrar nos documentos, mas o tcpdump mostra que há 3 segundos. atraso entre o 1º SYN enviado e a 2ª tentativa de enviar SYN.
fonte