176

我将 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"
4

10 回答 10

195

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

proxy_connect_timeout       300;
proxy_send_timeout          300;
proxy_read_timeout          300;
send_timeout                300;
于 2014-09-19T08:25:53.517 回答
119

增加超时不太可能解决您的问题,因为正如您所说,实际的目标 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

于 2016-04-13T05:13:35.120 回答
33

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

解决方案在这个论坛帖子中,它说你应该把你的超时设置放在/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中的超时更改没有做任何事情,我希望这个答案有帮助!

于 2019-02-09T10:05:16.287 回答
21

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

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

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.

于 2018-05-06T15:48:02.107 回答
19

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

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

一旦缓存条目过期,您可以告诉 nginx 使用名称服务器重新解析域:

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”(tenzer.dk)的详细解释,其中还包含一些有关此方法关于转发 URI 的警告的相关信息。

于 2018-09-13T10:03:11.303 回答
2

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

于 2018-08-19T21:50:48.507 回答
1

nginx

proxy_read_timeout          300;

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

于 2021-11-18T15:46:37.347 回答
1

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

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

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

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

GCP 的这份文档将帮助您了解 NAT 与 NGINX 504 超时的关系。

于 2020-06-12T20:23:54.217 回答
0

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

于 2021-01-20T15:42:33.203 回答
0

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

于 2020-06-23T11:00:41.240 回答