Proxy reverso Nginx causando 504 Tempo limite do gateway

127

Estou usando o Nginx como um proxy reverso que recebe solicitações e executa um proxy_pass para obter o aplicativo Web real do servidor upstream em execução na porta 8001.

Se eu for ao mywebsite.com ou fizer um wget, recebo um Tempo limite do gateway 504 após 60 segundos ... No entanto, se eu carregar o mywebsite.com:8001, o aplicativo será carregado conforme o esperado!

Então, algo está impedindo que o Nginx se comunique com o servidor upstream.

Tudo isso começou depois que minha empresa de hospedagem redefiniu a máquina em que minhas coisas estavam funcionando, antes disso não havia problema algum.

Aqui está o meu bloco de servidor vhosts:

server {
    listen   80;
    server_name mywebsite.com;

    root /home/user/public_html/mywebsite.com/public;

    access_log /home/user/public_html/mywebsite.com/log/access.log upstreamlog;
    error_log /home/user/public_html/mywebsite.com/log/error.log;

    location / {
        proxy_pass http://xxx.xxx.xxx.xxx:8001;
        proxy_redirect off;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
} 

E a saída do meu log de erro do Nginx:

2014/06/27 13:10:58 [error] 31406#0: *1 upstream timed out (110: Connection timed out) while connecting to upstream, client: xxx.xx.xxx.xxx, server: mywebsite.com, request: "GET / HTTP/1.1", upstream: "http://xxx.xxx.xxx.xxx:8001/", host: "mywebsite.com"
Dave Roma
fonte
O servidor está executando o SELinux?
CrackerJack9
No meu caso, o gateway NAT era o problema, não o NGINX ou a API de back-end. stackoverflow.com/a/62351959/9956279
Sushilinux 13/06

Respostas:

152

Provavelmente, pode adicionar mais algumas linhas para aumentar o período de tempo limite para upstream. Os exemplos abaixo definem o tempo limite para 300 segundos:

proxy_connect_timeout       300;
proxy_send_timeout          300;
proxy_read_timeout          300;
send_timeout                300;
user2540984
fonte
5
Penso que aumentar o tempo limite raramente é a resposta, a menos que você saiba que sua rede / serviço sempre ou em alguns casos responde muito lentamente. Poucos web pede hoje em dia deve levar mais do que alguns segundos a menos que você está baixando conteúdo (arquivos / imagens)
Almund
@ Almund Eu pensei a mesma coisa (quase não me incomodei em tentar isso), mas por qualquer motivo isso só funcionou para mim. (O tempo limite expirou anteriormente após 60 segundos, agora obtenha resposta imediatamente).
Dax Fohl
@Dax Fohl: Isso é curioso. Eu puxei a fonte e dei uma olhada rápida e, pelo que posso ver, definir qualquer configuração de proxy além do proxy_pass inicializará um monte de configurações que eu presumo que executem o proxy de uma maneira diferente, portanto, talvez definir algo dê o mesmo comportamento.
Almund 18/04/19
Não resolveu o problema para mim usá-lo com um servidor nodejs
VPX
3
Acho que só preciso proxy_read_timeoutquando depurar no back-end. obrigado!
precisa
79

Aumentar o tempo limite provavelmente não resolverá seu problema, pois, como você diz, o servidor Web de destino real está respondendo perfeitamente.

Eu tive esse mesmo problema e achei que tinha a ver com não usar um keep-alive na conexão. Na verdade, não posso responder por que isso ocorre, mas, ao limpar o cabeçalho da conexão, resolvi esse problema e a solicitação foi submetida a um proxy bem:

server {
    location / {
        proxy_set_header   X-Real-IP $remote_addr;
        proxy_set_header   Host      $http_host;
        proxy_http_version 1.1;
        proxy_set_header Connection "";
        proxy_pass http://localhost:5000;
    }
}

Dê uma olhada nessas postagens, que a explicam com mais detalhes: nginx fecha a conexão upstream após solicitação Esclarecimento do cabeçalho keep -alive http://nginx.org/en/docs/http/ngx_http_upstream_module.html#keepalive

Almund
fonte
7
Meses de problemas resolvidos por uma única linha proxy_set_header Connection "";lol, uso não faça runcloud
nodws
21

user2540984 , assim como muitos outros, apontaram que você pode tentar aumentar suas configurações de tempo limite. Eu mesmo enfrentei um problema semelhante a este e tentei alterar minhas configurações de tempo limite no arquivo /etc/nginx/nginx.conf , como quase todo mundo nesses tópicos sugere. Isso, no entanto, não me ajudou nem um pouco; não houve alterações aparentes nas configurações de tempo limite do NGINX. Após muitas horas de pesquisa, finalmente consegui resolver meu 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;

Isso pode não ser a solução para seu problema específico, mas se alguém notar que o tempo limite muda no /etc/nginx/nginx.conf não faz nada, espero que esta resposta ajude!

Andreas Forslöw
fonte
oi não há timeout.conf no meu diretório config.d. Você disse que o criou e quero confirmar, basta adicionar a configuração acima no timeout.conf?
tktktk0711 10/07/19
Sim, basta adicioná-los. Você pode modificá-los para suas próprias necessidades, mas elas funcionaram para mim!
Andreas Forslöw 23/07/19
Infelizmente, na propriedade do Laravel com o ubuntu e o Nginx, isso não funciona. :( Você quer apenas adicionar essas linhas? Sem server{}ou qualquer outra coisa? Esse erro aparece logo após 5 minutos. Eu recarrego, reinicializo e ele nunca passa além desses 5 minutos ou 300 segundos. Há mais idéias para corrigir -lo?
Patros
15

Se você deseja aumentar ou adicionar um limite de tempo a todos os sites, adicione linhas abaixo ao nginx.confarquivo.

Adicione linhas abaixo à httpseção /usr/local/etc/nginx/nginx.confou /etc/nginx/nginx.confarquivo.

fastcgi_read_timeout 600;
proxy_read_timeout 600;

Se as linhas acima não existirem no confarquivo, adicione-as; caso contrário, aumente fastcgi_read_timeoute proxy_read_timeoutverifique se o nginx e o php-fpm não atingiram o tempo limite.

Para aumentar o limite de tempo para apenas um site, você pode editar no vim /etc/nginx/sites-available/example.com

location ~ \.php$ {
    include /etc/nginx/fastcgi_params;
        fastcgi_pass  unix:/var/run/php5-fpm.sock;
    fastcgi_read_timeout 300; 
}

e depois de adicionar essas linhas nginx.conf, não esqueça de reiniciar o nginx.

service php7-fpm reload 
service nginx reload

ou, se você estiver usando manobrista, basta digitar valet restart.

Adeel
fonte
1
Obrigado obras para mim: #fastcgi_read_timeout 600; proxy_read_timeout 600;
Alejandro
13

Você também pode enfrentar essa situação se o servidor upstream usar um nome de domínio e o endereço IP mudar (por exemplo: o upstream aponta para um AWS Elastic Load Balancer)

O problema é que o nginx resolverá o endereço IP uma vez e o manterá em cache para solicitações subsequentes até que a configuração seja recarregada.

Você pode dizer ao nginx para usar um servidor de nomes para resolver novamente o domínio quando a entrada em cache expirar:

location /mylocation {
    # use google dns to resolve host after IP cached expires
    resolver 8.8.8.8;
    set $upstream_endpoint http://your.backend.server/;
    proxy_pass $upstream_endpoint;
}

Os documentos em proxy_pass explicam por que esse truque funciona:

O valor do parâmetro pode conter variáveis. Nesse caso, se um endereço for especificado como um nome de domínio, o nome será pesquisado entre os grupos de servidores descritos e, se não for encontrado, será determinado usando um resolvedor.

Parabéns ao "Nginx com fluxos dinâmicos" (tenzer.dk) para obter a explicação detalhada, que também contém algumas informações relevantes sobre uma ressalva dessa abordagem em relação aos URIs encaminhados.

el.atomo
fonte
1
essa resposta é ouro, exatamente o que aconteceu comigo. upstream aponta para aws elb e todo o súbito tempo limite do Gateway.
Nathan Do
2

Teve o mesmo problema. Aconteceu que foi causado pelo rastreamento da conexão iptables no servidor upstream. Após a remoção --state NEW,ESTABLISHED,RELATEDdo script do firewall e a liberação conntrack -Fdo problema se foi.

mindlab
fonte
0

O próprio NGINX pode não ser a causa raiz.

Se as "portas mínimas por instância da VM" definidas no Gateway NAT - que ficam entre a instância do NGINX e o proxy_passdestino - são muito pequenas para o número de solicitações simultâneas, elas precisam ser aumentadas.

Solução: aumente o número disponível de portas por VM no gateway NAT.

Contexto No meu caso, no Google Cloud, um proxy reverso NGINX foi colocado dentro de uma sub-rede, com um Gateway NAT. A instância NGINX estava redirecionando solicitações para um domínio associado à nossa API de back-end (upstream) por meio do Gateway NAT.

Esta documentação do GCP ajudará você a entender como o NAT é relevante para o tempo limite do NGINX 504.

Sushilinux
fonte
-1

No meu caso, eu reinicio o php e fica ok.

Mahdy Aslamy
fonte