O que é keepalive?
A idéia por trás do keepalive é abordar a latência de estabelecer conexões TCP em redes de alta latência. É necessário um handshake de 3 vias para estabelecer uma conexão TCP, portanto, quando há uma latência perceptível entre o cliente e o servidor, o keepalive aceleraria muito as coisas reutilizando as conexões existentes.
Por que as pessoas colocam o nginx na frente de seus backends?
O Nginx é muito eficiente em fazer malabarismos com milhares de conexões, enquanto muitos backends não estão, portanto, acelerando as coisas, as pessoas geralmente colocam o nginx na frente de seus servidores web reais para acelerar as coisas, para que as conexões entre a nuvem e o o usuário seria mantido em cache para reutilização subseqüente.
Observe que o nginx nem mesmo suportava upstream
keepalive
até 1.1.4, conforme o link , já que conforme acima, é mais provável que você use mais recursos do seu upstream do que acelerar qualquer processamento, desde que você tenha latência de sub-milissegundos entre todos os seus hosts (por exemplo, entre o nginx e os servidores upstream).
Você vê aonde está indo?
Ao usar um número excessivo de conexões keepalive em uma LAN, em algumas centenas por servidor upstream, você provavelmente só estará tornando as coisas mais lentas, não mais rápidas, mesmo que não tenha enfrentado o problema descrito por você.
O que acontece quando um serviço / porta está inoperante?
Normalmente, quando uma determinada porta está indisponível no host, o host retorna imediatamente um pacote de redefinição TCP, conhecido como RST
, que informa imediatamente ao cliente (por exemplo, nginx) o que está acontecendo, permitindo que ele tome as ações apropriadas imediatamente. (Pacotes diferentes de RST
também podem ser usados para o mesmo efeito, por exemplo, quando a rota para o host não está disponível.)
If we stop the service on the backend, nginx handles it correctly. The issue only reproduces when stopping the entire VM. – Ramiro Berrelleza Oct 27 at 22:48
O seu comentário acima provavelmente indica que é a falta de pacotes de conexão negados oportunamente que certamente confundem o nginx - parece provável que sua configuração esteja simplesmente descartando os pacotes que o nginx envia. E sem qualquer resposta às solicitações, como alguém poderia saber se seu serviço de back-end está indisponível, em vez de simplesmente exibir um comportamento em nível corporativo?
O que se deve fazer?
-
Primeiro, como já mencionado, mesmo que você não tenha tido os problemas descritos, é provável que você esteja apenas tornando as coisas mais lentas usando a funcionalidade
upstream
keepalive
em uma LAN, especialmente com essa número alto. -
Caso contrário, você pode configurar sua configuração (firewall, roteador, ambiente de virtualização, etc) para retornar pacotes apropriados para hosts indisponíveis, o que certamente deve fazer o nginx funcionar como esperado, já que você já testou o que acontece quando os pacotes TCP RST são, de fato, retornados pelo host.
-
Outra opção é ajustar os vários timeouts dentro do nginx, para considerar a possibilidade de seus upstream desaparecerem sem deixar vestígios, e para compensar sua rede não sendo capaz de gerar os pacotes de controle apropriados.
Isso pode incluir o
connect(2)
tempo limite, para estabelecer novas conexões TCP, via link no intervalo de milissegundos (por exemplo, se todos os servidores estiverem em uma rede local e você NÃO estiver executando software de nível empresarial com atrasos em vários níveis no nível corporativo ), bem como os tempos limite pararead(2)
em curso esend(2)
das operações, através do link e link , respectivamente, o que dependeria da rapidez com que o aplicativo de backend deve responder às solicitações. Talvez você também queira aumentar o parâmetrofail_timeout
da diretivaserver
dentro do contextoupstream
, conforme link .