简体   繁体   English

使用 Docker 的 Nginx 504 网关超时

[英]Nginx 504 gateway timeout with Docker

I'm using PHP and Apache with nginx for a reverse proxy, all on Docker, and I have a couple of long running calls that are timing after 60 seconds, resulting in a 504 Gateway Time-out.我将 PHP 和 Apache 与 nginx 一起用于反向代理,全部在 Docker 上,并且我有几个长时间运行的调用在 60 秒后计时,导致 504 网关超时。 I know my app is being called successfully because I'm tailing my PHP app's log and I can see it actively writing to the log.我知道我的应用程序被成功调用,因为我正在跟踪我的 PHP 应用程序的日志,我可以看到它正在积极地写入日志。 Every single time it's a 60 second timeout, but I can't seem to figure out where that setting is.每次都是 60 秒超时,但我似乎无法弄清楚该设置在哪里。

I tried the suggestions in this post , but nothing worked.我尝试了这篇文章中的建议,但没有任何效果。 I've updated my php.ini file with a few time related settings and I've verified they're being set with phpinfo我已经用一些时间相关的设置更新了我的 php.ini 文件,并且我已经验证它们是用 phpinfo 设置的

max_input_time = 0
max_execution_time = 500

I also increased the memory limit to 512, but considering it times out in about 60 seconds every single time I don't think that's the issue.我还将内存限制增加到 512,但考虑到它每次都会在大约 60 秒内超时,我认为这不是问题所在。

As far as updating nginx settings, I initially followed this tutorial on adjusting nginx-proxy timeout, but that didn't work.至于更新 nginx 设置,我最初是按照本教程调整 nginx-proxy 超时,但这不起作用。 I undid the changes, then ssh'd into the container and manually updated /etc/nginx/nginx.conf, here's what the http section looks like我取消了更改,然后 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;
}

I made sure to run nginx -s reload after updating the nginx.conf file.我确保在更新 nginx.conf 文件后运行nginx -s reload I'm not sure where else to look, because everything I've come across is pretty much what I've done already.我不知道还有什么地方可以看,因为我遇到的一切几乎都是我已经做过的。 What else could be causing nginx to timeout after 60 seconds?还有什么可能导致 nginx 在 60 秒后超时? Thanks谢谢

Here's my PHP dockerfile这是我的 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

The issue is that nginx has it's own timeouts.问题是 nginx 有它自己的超时。 Ideally, you'd sync nginx and PHP.理想情况下,您应该同步 nginx 和 PHP。 I can't speak to Apache here as I don't know what mode you're running it with (FPM or mod_php).我无法在这里与 Apache 交谈,因为我不知道您使用的是哪种模式(FPM 或 mod_php)。 I'm also not exactly sure why you're running Nginx and Apache, but, if you're getting a 504 response, and PHP is still processing the request, Nginx is terminating the request and returning the 504 response.我也不确定您为什么要运行 Nginx 和 Apache,但是,如果您收到 504 响应,而 PHP 仍在处理该请求,Nginx 将终止该请求并返回 504 响应。 Nginx doesn't run like Apache with mod_php where the processes are one in the same. Nginx 不像 Apache 使用 mod_php 那样运行,其中进程是相同的。 Nginx is going to relay the request and wait for whatever process to return a response. Nginx 将转发请求并等待任何进程返回响应。

See the following settings from our configs regarding timeouts from 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;

This answer may help those who use cloud, placing reverse proxy NGINX instance within a subnet, with NAT Gateway associated.这个答案可以帮助那些使用云的人,将反向代理 NGINX 实例放置在子网中,并关联 NAT 网关。

I also struggled with 504 upstream timeout error.我也遇到了 504 上游超时错误。 As described in the link, it was neither NGINX nor the backend API's failure.如链接中所述,这既不是 NGINX 也不是后端 API 的故障。

NAT Gateway was only accepting limited number of connection at the same time. NAT 网关同时只接受有限数量的连接。

This resulted in NGINX not being able to connect to the upstream.这导致 NGINX 无法连接到上游。

This config solved the issue for me这个配置为我解决了这个问题

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 "";
        ...
    }
}

Especially adding proxy_set_header Connection "";特别是添加proxy_set_header Connection "";

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM