Solicitações de buffer para o nginx por um curto período de tempo se o backend estiver inativo

7

Eu tenho um aplicativo nodejs sempre correndo atrás do nginx. Quando eu implantar novo código, eu só faço forever restart , mas não posso me dar ao luxo de obter 502 mesmo nesse curto período de tempo.

Como configurar o nginx para continuar tentando neste servidor upstream no caso de 502? Tentei definir proxy_connect_timeout , proxy_read_timeout e proxy_send_timeout como, por exemplo 30s mas imediatamente recebo 502 não importa o que: (

Meu site conf é:

upstream my_server {
  server 127.0.0.1:3000 fail_timeout=0;
  keepalive 1024;
}

server {
 listen 3333;

server_name myservername.com;
access_log /var/log/nginx/my_server.log;

location / {
  proxy_set_header X-Real-IP $remote_addr;
  proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
  proxy_set_header Host $http_host;
  proxy_set_header X-NginX-Proxy true;

  # retry upstream on 502 error
  proxy_connect_timeout      30s;
  proxy_send_timeout         30s;
  proxy_read_timeout         30s;

  proxy_pass http://my_server;
  proxy_http_version 1.1;
  proxy_set_header Connection "";
  proxy_redirect off;
 }
}

É possível fazer buffer de pedidos para este curto período de tempo quando o upstream não está disponível?

    
por Marin 07.11.2013 / 12:42

1 resposta

1

Isso soa como um problema com o seu back-end: nginx faz um pedido para seu backend, a conexão é recusada imediatamente, então, nginx não tem outra opção para passar um erro downstream para o usuário, já que nenhum outro upstream é especificado, e os valores de timeout que você especificar não terão nenhum efeito aqui, já que o nginx não precisa esperar nada.

Eu não sei agora o que é forever , ou como funciona, mas há algumas possíveis soluções que vêm à mente.

Existem duas possibilidades do que está acontecendo no lado de cima:

  • "Para sempre" pode aceitar a conexão e retornar um erro imediatamente. Nesse caso, parece que o que você realmente deveria estar perguntando é como fazer com que a conexão não seja mal administrada, mas espere até que o aplicativo termine a implantação e processe a solicitação até lá. O opengrok app no servidor tomcat tem esse problema.

  • Ninguém está escutando na porta em que seu aplicativo deve rodar, portanto, o kernel está descartando o pacote imediatamente e retornar um pacote TCP RST imediatamente.

    • Se TCP RST for a causa, você poderá resolvê-lo com forever mantendo o soquete de escuta ou configurando o kernel para enfileirar pacotes de entrada por um certo tempo, antecipando que alguém os encontre mais tarde on, para que quando forever iniciar o backup, ele tenha uma fila inteira pronta para manutenção.

    • Configure o kernel para não emitir TCP RST quando ninguém estiver ouvindo, então seu timeout em nginx terá um efeito. Posteriormente, configure nginx para fazer uma segunda solicitação para outro desenvolvedor.

Se você abordar um dos casos acima, estará pronto.

Senão, você precisa tentar configurar o nginx para corrigir o problema:

  • Você pode tentar proxy_cache com proxy_cache_use_stale .

  • Você pode tentar usar o manipulador de erros: consulte proxy_intercept_errors (provavelmente se aplica somente se o 503 que você está obtendo é passado do seu back-end) e error_page . Você pode perder tempo no manipulador de erros, até que seu aplicativo volte a ser exibido e faça uma solicitação ao seu aplicativo.

    • Você pode perder tempo executando um segundo aplicativo, que simplesmente faria um sleep() por quanto tempo for necessário para que seu aplicativo seja reimplantado, forneça um redirecionamento HTTP ou saia sem uma resposta; diabos, você poderia simplesmente implementar isso tentando fazer proxy para uma porta TCP que você block drop no firewall, o que ativaria seus tempos limite em nginx. Posteriormente, configure o nginx para fazer uma segunda solicitação.

Se você implementar uma das abordagens acima que envolva timeout de ativação, ela subseqüentemente exigirá que uma solicitação extra para o back-end seja feita. Você pode usar a diretiva upstream para isso, em que você pode especificar o mesmo servidor várias vezes ou, se não for aceito, pode espelhar uma porta através de seu firewall ou, melhor ainda, você pode executar vários servidores de aplicativos independentes em primeiro lugar.

O que nos traz de volta ao seu servidor de aplicativos: se ele não puder lidar com o problema da reimplantação limpa, talvez seja necessário executar dois desses servidores de aplicativos e usar o nginx para balancear a carga entre eles. Ou implante-os novamente e, em seguida, mude o nginx para a nova cópia quando ela estiver realmente pronta. Além disso, como você poderia ter certeza de que seus clientes estariam dispostos a esperar até 30 segundos para que sua API respondesse?

    
por 04.12.2013 / 05:59

Tags