使用PHP set_time_limit()防止nginx 504网关超时


Prevent nginx 504 Gateway timeout using PHP set_time_limit()

当我的PHP脚本运行时间比平时长时,我从nginx收到504条超时消息。set_time_limit(0)似乎无法阻止!在nginx上运行php5-fpm时,它不起作用吗?如果是,设定时限的正确方法是什么?

错误:

504 Gateway Time-out
nginx/1.2.7

有几种方法可以设置php-fpm的超时。在/etc/php5/fpm/pool.d/www.conf中,我添加了以下行:

request_terminate_timeout = 180

此外,在/etc/nginx/sites-available/default中,我在有问题的服务器的位置块中添加了以下行:

fastcgi_read_timeout 180;

整个位置块如下所示:

location ~ '.php$ {
    fastcgi_pass unix:/var/run/php5-fpm.sock;
    fastcgi_index index.php;
    fastcgi_param   SCRIPT_FILENAME $document_root$fastcgi_script_name;
    fastcgi_read_timeout 180;
    include fastcgi_params;
} 

现在只要重新启动php-fpm和nginx,就不会再有超过180秒的请求超时。

试试这个链接,它有一个更好的解决方案来解决这个问题。因此,步骤是:

  1. 打开位于/etc/nginx目录中的nginx.conf文件
  2. http {部分下添加以下代码:

    client_header_timeout 3000;
    client_body_timeout 3000;
    fastcgi_read_timeout 3000;
    client_max_body_size 32m;
    fastcgi_buffers 8 128k;
    fastcgi_buffer_size 128k;
    

    注意:如果它已经存在,请根据更改值。

  3. 重新加载Nginx和php5-fpm。

    $ service nginx reload
    $ service php5-fpm reload
    

    如果错误仍然存在,请考虑增加值。

您不能使用PHP来防止nginx发出超时。

要配置nginx以允许更多时间,请参阅proxy_read_timeout指令。

正确答案是在Nginx配置中增加fastcgi_read_timeout
就这么简单!

 sudo nano /etc/nginx/nginx.conf

将这些变量添加到nginx.conf文件:

http {  
  # .....
  proxy_connect_timeout       600;
  proxy_send_timeout          600;
  proxy_read_timeout          600;
  send_timeout                600;
}

然后重新启动:

service nginx reload

在这种情况下可能发生三种超时。可以看出,每个答案都只关注这些可能性的一个方面。所以,我想把它写下来,这样将来来这里的人就不需要在不知道哪一个有效的情况下随机检查每个答案并获得成功。

  1. 请求者的请求超时-需要设置超时标头(请参阅请求库中的标头配置(
  2. 发出请求时从nginx超时(在转发到代理服务器之前(,例如:上传的巨大文件
  3. 转发到代理服务器后超时,服务器没有及时回复nginx。例如:在服务器上运行耗时的脚本

因此,每个问题的修复方法如下

  1. 设置超时标头,例如:在ajax 中

    $.ajax({
        url: "test.html",
        error: function(){
            // will fire when timeout is reached
        },
        success: function(){
            //do something
        },
        timeout: 3000 // sets timeout to 3 seconds
    });
    
  2. nginx客户端超时

    http{
         #in seconds
        fastcgi_read_timeout 600;
        client_header_timeout 600;
        client_body_timeout 600;
     }
    
  3. nginx代理服务器超时

    http{
      #Time to wait for the replying server
       proxy_read_timeout 600s;
    }
    

所以使用你需要的。也许在某些情况下,您需要所有这些配置。我需要。

您需要在nginx.conf中添加额外的nginx指令(用于ngx_http_proxy_module(,例如:

proxy_read_timeout 300;

基本上,nginx proxy_read_timeout指令更改代理超时,FcgidIOTimeout用于静默时间过长的脚本,FcgidBusyTimeout用于执行时间过长的剧本。

此外,如果您正在使用FastCGI应用程序,请增加以下选项:

FcgidBusyTimeout 300
FcgidIOTimeout 250

然后重新加载发动机和PHP5-FPM。

Plesk

在Plesk中,您可以在其他nginx指令下的Web服务器设置中添加它。

对于FastCGI,请检查HTTP附加指令下的Web服务器设置

请参阅:如何修复Plesk中的FastCGI超时问题

不要忘记查看您的php-fpm日志!

在我的PHP 7.3案例中,我遇到了:

警告:[pool www]服务器已达到pm.max_children设置(5(,考虑提高

/etc/php/7.3/fpm/pool.d/www.conf上,我不得不将pm.max_children的值从5提高到50(我有时会做一些相当重的本地工作…(

注意:请注意,它可能会使用更多的CPU

由于您使用的是php-fpm,您应该利用fastcgi_finish_request((来处理您知道可能需要更长时间的请求。

使用php-fpm或类似的流程管理器时,使用set_time_limit(0)是无用的。

底线是在使用php-fpm时不要使用set_time_limit,为了增加执行超时,请查看本教程。

在花了很长时间寻找这个问题的答案后,我看到了一件事。

我的应用程序还有一层:

  1. 负载均衡器(问题一直存在(
  2. 网络服务器(nginx(
  3. 应用程序(php(

从向LB提出请求中逃脱,我可以在测试中看到成功的回应;睡眠;在php中。

对于我的情况,我在60秒左右正确设置了所有可能的TimeOut,但仍然出现了504 Gateway timeout错误,然后我想知道为什么在浏览器控制台中检查请求后,它总是在15秒左右超时!

在检查了我的其他Apache2配置文件后;15s";只是放在TimeOut选项的文件qos.conf(来自服务质量模块(中!所以我把它改为30,我的问题就解决了(事实上,这个请求只需要大约19秒就可以完成,所以它太接近了(。如果没有其他方法,我希望这能帮助到别人。

进入服务器

sudo nano/etc/nginx/nginix.conf

在HTTP部分添加504(网关超时(状态的配置,如下所示:

proxy_read_timeout 3600;

然后重新启动Nginx的服务器,它运行良好

sudo systemctl restart nginx