Nginx 反向代理导致 504 网关超时

Posted

技术标签:

【中文标题】Nginx 反向代理导致 504 网关超时【英文标题】:Nginx reverse proxy causing 504 Gateway Timeout 【发布时间】:2014-08-18 15:44:47 【问题描述】:

我使用 nginx 作为反向代理,它接受请求,然后执行 proxy_pass 从运行在端口 8001 上的上游服务器获取实际的 Web 应用程序。

如果我访问 mywebsite.com 或执行 wget,我会在 60 秒后收到 504 Gateway Timeout... 但是,如果我加载 mywebsite.com:8001,应用程序会按预期加载!

所以有些东西阻止了 Nginx 与上游服务器通信。

这一切都是在我的托管公司重置运行我的东西的机器之后开始的,在此之前没有任何问题。

这是我的虚拟主机服务器块:

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;
    
 

以及我的 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"

【问题讨论】:

服务器是否运行 SELinux? 在我的案例中,问题在于 NAT 网关,而不是 NGINX 或后端 API。 ***.com/a/62351959/9956279 【参考方案1】:

nginx

proxy_read_timeout          300;

在我使用 AWS 的情况下,我还编辑了负载平衡设置。 属性 => 空闲超时

【讨论】:

【参考方案2】:

如果使用了 nginx_ajp_module,请尝试添加 ajp_read_timeout 10m; 在 nginx.conf 文件中。

【讨论】:

【参考方案3】:

NGINX 本身可能不是根本原因。

IF 在 NAT 网关(位于 NGINX 实例和proxy_pass 目标之间)设置的“每个 VM 实例的最小端口”对于并发请求的数量来说太小了,它必须增加。

解决方案:增加 NAT 网关上每个 VM 的可用端口数。

上下文在我的例子中,在 Google Cloud 上,一个反向代理 NGINX 被放置在一个带有 NAT 网关的子网内。 NGINX 实例通过 NAT 网关将请求重定向到与我们的后端 API(上游)关联的域。

This documentation from GCP 将帮助您了解 NAT 与 NGINX 504 超时的关系。

【讨论】:

【参考方案4】:

在我的情况下,我重新启动 php,它就可以了。

【讨论】:

从所有答案中尝试了上述所有步骤,但最后,这行得通,有时我们只是错过了最小的事情。【参考方案5】:

遇到了同样的问题。原来这是由上游服务器上的 iptables 连接跟踪引起的。从防火墙脚本中删除--state NEW,ESTABLISHED,RELATED 并使用conntrack -F 刷新后,问题就消失了。

【讨论】:

【参考方案6】:

user2540984,以及许多其他人指出,您可以尝试增加超时设置。正如这些线程中的几乎每个人所建议的那样,我自己也遇到了与此类似的问题,并尝试更改 /etc/nginx/nginx.conf 文件中的超时设置。然而,这对我一点帮助也没有。 NGINX 的超时设置没有明显变化。经过几个小时的搜索,我终于设法解决了我的问题。

解决方案在this forum thread,它的意思是你应该把你的超时设置放在/etc/nginx/conf.d/timeout.conf (如果这个文件不存在,你应该创建它)。我使用了与线程中建议的相同的设置:

proxy_connect_timeout 600;
proxy_send_timeout 600;
proxy_read_timeout 600;
send_timeout 600;

这可能不是您特定问题的解决方案,但是如果其他人注意到 /etc/nginx/nginx.conf 中的超时更改没有做任何事情,我希望这个答案会有所帮助!

【讨论】:

嗨,我的 config.d 目录中没有 timeout.conf。你说创建它,我想确认它只是在 timeout.conf 中添加上述设置? 是的,只需添加它们。您可以根据自己的需要修改它们,但这些对我有用! 不幸的是,在带有 ubuntu 和 Nginx 的 Laravel 宅基地中,这不起作用。 :( 你的意思是只添加这些行吗?没有server 或其他什么?这个错误在 5 分钟后出现。我重新加载,重新启动,它永远不会超过 5 分钟或 300 秒。还有更多修复它的想法? 在你的 nginx.conf 主配置文件中,你没有提到这个 timeout.conf 文件包含在哪里。最后,Nginx 只有一个配置文件,其中包含所有 .conf 文件。我认为它对您有用,因为您将超时时间增加到 600。【参考方案7】:

如果您的上游服务器使用域名,您也可能会遇到这种情况,并且 它的 IP 地址更改(例如:您的上游指向 AWS Elastic Load 平衡器)

问题是nginx会解析一次IP地址,并保持缓存 用于后续请求,直到重新加载配置。

你可以告诉 nginx 使用名称服务器来re-resolve 缓存后的域 条目过期:

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;

proxy_pass 上的文档解释了为什么这个技巧有效:

参数值可以包含变量。在这种情况下,如果指定了地址 作为域名,在所描述的服务器组中搜索该名称,并且, 如果未找到,则使用解析器确定。

感谢"Nginx with dynamic upstreams" (tenzer.dk) 了解详细信息 解释,其中还包含有关此警告的一些相关信息 关于转发 URI 的方法。

【讨论】:

这个答案是金,正是发生在我身上的事情。上游指向 aws elb 和所有突然的网关超时。【参考方案8】:

如果您想增加或添加所有站点的时间限制,那么您可以在nginx.conf 文件中添加以下行。

将以下行添加到/usr/local/etc/nginx/nginx.conf/etc/nginx/nginx.conf 文件的http 部分。

fastcgi_read_timeout 600;
proxy_read_timeout 600;

如果conf文件中不存在上述行,则添加它们,否则增加fastcgi_read_timeoutproxy_read_timeout以确保nginx和php-fpm没有超时。

要增加仅一个站点的时间限制,您可以在 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; 

nginx.conf中添加这些行之后,别忘了重启nginx。

service php7-fpm reload 
service nginx reload

或者,如果您使用代客服务,则只需输入 valet restart

【讨论】:

感谢为我工作:fastcgi_read_timeout 600;proxy_read_timeout 600;【参考方案9】:

增加超时不太可能解决您的问题,因为正如您所说,实际的目标 Web 服务器响应正常。

我遇到了同样的问题,我发现它与未在连接上使用保持连接有关。我实际上无法回答为什么会这样,但是在清除连接标头时我解决了这个问题并且请求被代理得很好:

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;
    

看看这篇文章,它更详细地解释了它: nginx close upstream connection after request Keep-alive header clarification http://nginx.org/en/docs/http/ngx_http_upstream_module.html#keepalive

【讨论】:

单行解决了几个月的问题proxy_set_header Connection ""; 哈哈,不要使用runcloud 我们有一个代理在源超时时需要 5 秒以上才能响应。这成功了。谢谢!【参考方案10】:

可能可以多添加几行来增加上游的超时时间。以下示例将超时设置为 300 秒:

proxy_connect_timeout       300;
proxy_send_timeout          300;
proxy_read_timeout          300;
send_timeout                300;

【讨论】:

我认为增加超时很少是答案,除非您知道您的网络/服务将始终或在某些情况下响应非常缓慢。除非您正在下载内容(文件/图像),否则现在很少有网络请求需要超过几秒钟的时间 在 nodejs 服务器上使用它并没有解决我的问题 我发现我在后端调试时只需要proxy_read_timeout。谢谢! 我们具体应该在哪里添加这些行? 我必须将client_max_body_size 的值从默认的1m 更改为5m,以解决此错误的问题。我正在代理一个 Flask 应用程序,该应用程序将上传图像并对其进行一些处理。对于一些较大的文件,我收到了这个错误。为了修复这个错误,我没有更改任何默认的超时值。

以上是关于Nginx 反向代理导致 504 网关超时的主要内容,如果未能解决你的问题,请参考以下文章

Nginx反向代理报504超时错误

Nginx反向代理报504超时错误

Docker 的 Nginx 504 网关超时

使用 Spring 云网关和 Nginx 作为反向代理的网关超时

502 503 504

让Nginx反向代理不再超时