O NGINX continua enviando pedidos para o upstream off-line

4

Eu tenho a seguinte configuração de balanceamento de carga:

upstream upstream {
  ip_hash;
  keepalive 1000;
  server 10.10.10.1;
  server 10.10.10.2;
  server 10.10.10.3;
}

server {
  listen                  443;
  server_name             example.com;
  ssl_certificate         /etc/nginx/certs/cert.crt;
  ssl_certificate_key     /etc/nginx/certs/cert.key;

  ssl on;
  ssl_session_cache  builtin:1000  shared:SSL:10m;
  ssl_protocols  TLSv1 TLSv1.1 TLSv1.2;
  ssl_ciphers HIGH:!aNULL:!eNULL:!EXPORT:!CAMELLIA:!DES:!MD5:!PSK:!RC4;
  ssl_prefer_server_ciphers on;

  location / {
      client_max_body_size        80m;
      proxy_http_version          1.1;
      proxy_set_header Connection "";
      proxy_set_header            Host $host;
      proxy_set_header            X-Real-IP $remote_addr;
      proxy_set_header            X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_set_header            X-Forwarded-Proto $scheme;
      proxy_read_timeout          90;
      proxy_pass                  http://upstream;
  }
}

Embora meus nós de back-end estejam estáveis, tudo funciona bem. No entanto, quando eu desligar um dos nós (por exemplo, 10.10.10.2), o NGINX continuará enviando tráfego para ele, mesmo se as solicitações continuarem expirando (já que o servidor está desligado). Eu já tentei configurar os parâmetros max_fails e fail_timeout , mas o comportamento ainda é o mesmo.

O NGINX é capaz de detectar automaticamente se um servidor está inoperante e não enviar tráfego para lá? Que configuração estou faltando?

    
por Ramiro Berrelleza 27.10.2017 / 18:55

2 respostas

3

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 para read(2) em curso e send(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âmetro fail_timeout da diretiva server dentro do contexto upstream , conforme link .

por 12.11.2017 / 02:43
3

Tente definir keepalive 16 e teste novamente. 1k de conexões em cache por trabalhador pode ser demais para o seu caso.

    
por 09.11.2017 / 11:20

Tags