NGINX: tempo limite upstream excedido (110: tempo limite excedido da conexão) ao ler o cabeçalho da resposta upstream

130

Tenho o Puma em execução como servidor de aplicativos upstream e Riak como meu cluster db em segundo plano. Quando envio uma solicitação que mapeia um pedaço de dados para cerca de 25 mil usuários e os retorna de Riak para o aplicativo, recebo um erro no log do Nginx:

tempo limite upstream excedido (110: tempo limite excedido da conexão) ao ler o cabeçalho de resposta do upstream

Se eu consultar meu upstream diretamente sem o proxy nginx, com a mesma solicitação, obtenho os dados necessários.

O tempo limite do Nginx ocorre quando o proxy é inserido.

**nginx.conf**

http {
    keepalive_timeout 10m;
    proxy_connect_timeout  600s;
    proxy_send_timeout  600s;
    proxy_read_timeout  600s;
    fastcgi_send_timeout 600s;
    fastcgi_read_timeout 600s;
    include /etc/nginx/sites-enabled/*.conf;
}

**virtual host conf**

upstream ss_api {
  server 127.0.0.1:3000 max_fails=0  fail_timeout=600;
}

server {
  listen 81;
  server_name xxxxx.com; # change to match your URL

  location / {
    # match the name of upstream directive which is defined above
    proxy_pass http://ss_api; 
    proxy_set_header  Host $http_host;
    proxy_set_header  X-Real-IP  $remote_addr;
    proxy_set_header  X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_cache cloud;
    proxy_cache_valid  200 302  60m;
    proxy_cache_valid  404      1m;
    proxy_cache_bypass $http_authorization;
    proxy_cache_bypass http://ss_api/account/;
    add_header X-Cache-Status $upstream_cache_status;
  }
}

O Nginx tem várias diretivas de tempo limite. Não sei se estou perdendo algo importante. Qualquer ajuda seria muito apreciada ....

user2768537
fonte
Só deve expirar após 600s, não é? Você pode fingir cronometrar configurando um servidor tcp em 127.0.0.1:3000 que apenas aceita conexões e não faz nada com elas, para ver quanto tempo leva. Deveria ser 600s ...
rogerdpack 19/11/19

Respostas:

47

Isso acontece porque o seu upstream leva muito para responder à solicitação e o NGINX acha que o upstream já falhou no processamento da solicitação, por isso responde com um erro. Basta incluir e aumentar o proxy_read_timeout no locationbloco de configuração. A mesma coisa aconteceu comigo e usei o tempo limite de 1 hora para um aplicativo interno no trabalho:

proxy_read_timeout 3600;

Com isso, o NGINX aguardará uma hora (3600s) para que seu upstream retorne algo.

Sergio Gonzalez
fonte
6
Observe que ter proxy_read_timeoutna seção http pode não ajudar. Eu tenho a proxy_passdiretiva na seção local e somente lá a proxy_read_timeoutconfiguração fez a diferença. (nginx 1.16.0)
JonnyJD
Parece funcionar em http / servidor / local para mim ... talvez as coisas mudaram :)
rogerdpack
39

Você sempre deve evitar aumentar o tempo limite, duvido que o tempo de resposta do servidor back-end seja o problema aqui em qualquer caso.

Eu resolvi esse problema limpando o sinalizador de manutenção de conexão e especificando a versão http conforme a resposta aqui: https://stackoverflow.com/a/36589120/479632

server {
    location / {
        proxy_set_header   X-Real-IP $remote_addr;
        proxy_set_header   Host      $http_host;

        # these two lines here
        proxy_http_version 1.1;
        proxy_set_header Connection "";

        proxy_pass http://localhost:5000;
    }
}

Infelizmente, não consigo explicar por que isso funciona e não consegui decifrá-lo dos documentos mencionados na resposta vinculada. Portanto, se alguém tiver uma explicação, eu ficaria muito interessado em ouvi-la.

Almund
fonte
1
Por que você não ajustaria proxy_read_timeoutse sabia que o proxy (mesmo para um URL específico) exigia mais tempo de processamento?
Josh M.
Oi! Não lembro mais o problema exato, mas acho que não estava relacionado ao horário real do URL, mas sim que o tempo limite não estava sendo processado corretamente sem essas configurações.
Almund 5/10/19
@magicbacon isso foi anos atrás, então eu mal me lembro mais do caso, mas você mudou o $http_hostcerto? Suponho que não voaria para https. Também podem ser necessárias configurações adicionais para proxy de solicitações https.
Almund 6/12/19
+1 ... isso parece um hack estranho, mas na verdade é dos documentos oficiais :) nginx.org/en/docs/http/ngx_http_upstream_module.html#keepalive Eu tenho um problema um pouco diferente "conexão fechada antecipadamente ao ler a resposta header from upstream "quando eu uso a diretiva upstream com keepalive e o uso dessas duas linhas parece corrigi-lo.
Karussell
1
@ TimDavis eu vejo, talvez seja melhor. Eu acho que pode depender do tráfego, como neste post dizendo que é necessário para o WebSockets: serverlab.ca/tutorials/linux/web-servers-linux/…
Almund
26

Primeiro, descubra qual upstream está mais lento consultando o arquivo de log de erros nginx e ajuste o tempo limite de leitura de acordo no meu caso, foi fastCGI

2017/09/27 13:34:03 [error] 16559#16559: *14381 upstream timed out (110: Connection timed out) while reading response header from upstream, client:xxxxxxxxxxxxxxxxxxxxxxxxx", upstream: "fastcgi://unix:/var/run/php/php5.6-fpm.sock", host: "xxxxxxxxxxxxxxx", referrer: "xxxxxxxxxxxxxxxxxxxx"

Então eu tenho que ajustar o fastcgi_read_timeout na minha configuração do servidor

 location ~ \.php$ {
     fastcgi_read_timeout 240;
     ...
 }

Veja: postagem original

Ruberandinda Paciência
fonte
Aqui está uma maneira de adicionar informações de tempo a falha para ver quanto você "precisa" para aumentá-lo para: stackoverflow.com/questions/18627469/… FWIW
rogerdpack 19/19/19
10

No seu caso, ajuda um pouco de otimização no proxy, ou você pode usar "# time out settings"

location / 
{        

  # time out settings
  proxy_connect_timeout 159s;
  proxy_send_timeout   600;
  proxy_read_timeout   600;
  proxy_buffer_size    64k;
  proxy_buffers     16 32k;
  proxy_busy_buffers_size 64k;
  proxy_temp_file_write_size 64k;
  proxy_pass_header Set-Cookie;
  proxy_redirect     off;
  proxy_hide_header  Vary;
  proxy_set_header   Accept-Encoding '';
  proxy_ignore_headers Cache-Control Expires;
  proxy_set_header   Referer $http_referer;
  proxy_set_header   Host   $host;
  proxy_set_header   Cookie $http_cookie;
  proxy_set_header   X-Real-IP  $remote_addr;
  proxy_set_header X-Forwarded-Host $host;
  proxy_set_header X-Forwarded-Server $host;
  proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
Dimitrios
fonte
Para mim, faz diferença ter essas configurações na seção de localização . Tê-los no http seção não ajuda (pssibly porque eu também tinha proxy_passna localização seção.
JonnyJD
O que exatamente você está otimizando com essas declarações?
Vlad
9

Acho que esse erro pode ocorrer por vários motivos, mas pode ser específico para o módulo que você está usando. Por exemplo, eu vi isso usando o módulo uwsgi, então tive que definir "uwsgi_read_timeout".

Richard
fonte
2
Eu acho que uwsgi_read_timeout 3600; proxy_send_timeout 3600; proxy_read_timeout 3600; funciona para mim.
tyan
9

Eu recomendaria examinar error_logs, especificamente a parte a montante, onde mostra a montante a montante que está atingindo o tempo limite.

Em seguida, com base no que você pode ajustar proxy_read_timeout, fastcgi_read_timeoutou uwsgi_read_timeout.

Verifique também se a sua configuração está carregada.

Mais detalhes aqui Nginx upstream excedeu o tempo limite (por que e como corrigir)

gansbrest
fonte
4

Como muitas outras pessoas apontaram aqui, o aumento das configurações de tempo limite do NGINX pode resolver seu problema.

No entanto, aumentar as configurações de tempo limite pode não ser tão simples quanto sugerem muitas dessas respostas. Eu mesmo enfrentei esse problema e tentei alterar minhas configurações de tempo limite no arquivo /etc/nginx/nginx.conf , como quase todo mundo nesses tópicos sugere. Isso não me ajudou nem um pouco; não houve alterações aparentes nas configurações de tempo limite do NGINX. Agora, muitas horas depois, finalmente consegui resolver esse problema.

A solução está neste tópico do fórum , e o que diz é que você deve colocar suas configurações de tempo limite em /etc/nginx/conf.d/timeout.conf (e se esse arquivo não existir, você deve criá-lo). Eu usei as mesmas configurações sugeridas no tópico:

proxy_connect_timeout 600;
proxy_send_timeout 600;
proxy_read_timeout 600;
send_timeout 600;
Andreas Forslöw
fonte
1

Eu tive o mesmo problema e o resultado foi um erro "todos os dias" no controlador de rails. Não sei por que, mas na produção, o puma executa o erro repetidamente, causando a mensagem:

tempo limite upstream excedido (110: tempo limite excedido da conexão) ao ler o cabeçalho de resposta do upstream

Provavelmente porque o Nginx tenta obter os dados do puma repetidamente. O engraçado é que o erro causou a mensagem de tempo limite, mesmo que eu esteja chamando uma ação diferente no controlador, portanto, um único erro de digitação bloqueia todo o aplicativo.

Verifique seu arquivo log / puma.stderr.log para ver se é essa a situação.

aarkerio
fonte
0

Do nosso lado, estava usando spdy com cache proxy. Quando o cache expira, obtemos esse erro até que o cache seja atualizado.

timhaak
fonte
0

Espero que ajude alguém: eu encontrei esse erro e a causa foi a permissão errada na pasta de log do phpfpm, depois de alterá-lo para que o phpfpm pudesse escrever nele, estava tudo bem.

Maurício Otta
fonte
0

Por proxy_upstreamtempo limite, tentei a configuração acima, mas essas não funcionaram.

A configuração resolver_timeoutfuncionou para mim, sabendo que demorava 30 anos para produzir a mensagem de tempo limite upstream. Por exemplo, me.atwibble.com não pôde ser resolvido (110: Tempo limite da operação esgotado) .

http://nginx.org/en/docs/http/ngx_http_core_module.html#resolver_timeout

David Mercer
fonte