Docker 的 Nginx 504 网关超时

Posted

技术标签:

【中文标题】Docker 的 Nginx 504 网关超时【英文标题】:Nginx 504 gateway timeout with Docker 【发布时间】:2019-10-22 13:51:20 【问题描述】:

我将 php 和 Apache 与 nginx 一起用于反向代理,全部在 Docker 上,并且我有几个长时间运行的调用在 60 秒后计时,导致 504 网关超时。我知道我的应用程序被成功调用,因为我正在跟踪我的 PHP 应用程序的日志,并且我可以看到它正在积极地写入日志。每次都是 60 秒超时,但我似乎无法弄清楚该设置在哪里。

我尝试了this post 中的建议,但没有任何效果。我已经用一些时间相关的设置更新了我的 php.ini 文件,并且我已经验证了它们是用 phpinfo 设置的

max_input_time = 0
max_execution_time = 500

我还将内存限制增加到 512,但考虑到它每次都会在大约 60 秒内超时,我认为这不是问题。

至于更新 nginx 设置,我最初遵循 this tutorial 调整 nginx-proxy 超时,但这没有用。我撤消了更改,然后 ssh 进入容器并手动更新 /etc/nginx/nginx.conf,这是 http 部分的样子

http 
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    keepalive_timeout           500;
    proxy_connect_timeout       600;
    proxy_send_timeout          600;
    send_timeout                600;
    client_max_body_size        5000;
    client_header_timeout       600;
    client_body_timeout         600;
    fastcgi_read_timeout        300;

    #gzip  on;

    include /etc/nginx/conf.d/*.conf;

我确保在更新 nginx.conf 文件后运行nginx -s reload。我不知道还能去哪里看,因为我遇到的一切几乎都是我已经做过的。还有什么可能导致 nginx 在 60 秒后超时?谢谢

这是我的 PHP dockerfile

FROM php:7.2-fpm-alpine3.7

RUN apk update; \
    apk upgrade;

RUN docker-php-ext-install pdo_mysql

RUN apk add --no-cache php7-pear php7-dev gcc musl-dev make
RUN pecl install xdebug


RUN pecl install -o -f redis \
&&  rm -rf /tmp/pear \
&&  docker-php-ext-enable redis

【问题讨论】:

【参考方案1】:

问题是 nginx 有它自己的超时。理想情况下,您会同步 nginx 和 PHP。我不能在这里与 Apache 交谈,因为我不知道您使用什么模式运行它(FPM 或 mod_php)。我也不确定您为什么要运行 Nginx 和 Apache,但是,如果您收到 504 响应,并且 PHP 仍在处理请求,则 Nginx 正在终止请求并返回 504 响应。 Nginx 不像带有 mod_php 的 Apache 那样运行,其中进程是相同的。 Nginx 将中继请求并等待任何进程返回响应。

请参阅我们的配置中有关 Nginx 超时的以下设置。

# Timeouts
# The client_body_timeout and client_header_timeout directives are
# responsible for the time a server will wait for a client body or
# client header to be sent after request. If neither a body or header
# is sent, the server will issue a 408 error or Request time out.
#
# The keepalive_timeout assigns the timeout for keep-alive connections
# with the client. Simply put, Nginx will close connections with the
# client after this period of time.
#
# Finally, the send_timeout is a timeout for transmitting a response
# to the client. If the client does not receive anything within this
# time, then the connection will be closed. Send the client a "request
# timed out" if the body is not loaded by this time. Default 60.
client_body_timeout   32;
client_header_timeout 32;
# Every 60 seconds server broadcasts Sync packets, so 90 is a conservative upper bound. Default is 65
keepalive_timeout 90;
send_timeout 300;

【讨论】:

【参考方案2】:

This answer 可以帮助那些使用云的人,将反向代理 NGINX 实例放置在子网中,并关联 NAT 网关。

我还遇到了 504 上游超时错误。如链接中所述,这既不是 NGINX 也不是后端 API 的故障。

NAT 网关同时只接受有限数量的连接。

这导致 NGINX 无法连接到上游。

【讨论】:

【参考方案3】:

这个配置解决了我的问题

upstream http_backend 
    server 127.0.0.1:8080;

    keepalive 16;


server 
    ...

    location /http/ 
        proxy_pass http://http_backend;
        proxy_http_version 1.1;
        proxy_set_header Connection "";
        ...
    


特别是加proxy_set_header Connection "";

【讨论】:

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

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

nginx http 502 503 504区别 · T

增加 504 超时错误

nginx出现504错误的原因分析及解决

502 503 504

nginx报错504