Increase PHP-FPM idle timeout setting
Asked Answered
H

2

13

We have recently migrated to PHP-FPM. However we have encountered a problem with some long running scripts. The code looks roughly like:

foreach ($items as $item) {
     set_time_limit(30);
     proccessThatTakesAround2secs(); 
}

The normal PHP script time limit is also 30 secs. This was previously working fine in that we reset the remaining time limit back to 30 secs for each item. There are around 1000 items meaning the script in total would normally take about 30 mins to complete. However we have since reached the following problem:

FastCGI: comm with server "/usr/local/php-5.6.24/sbin/php5-fpm" aborted: idle timeout (30 sec)

Now my question is, is it sensible to increase the idle timeout to something like an hour but still ensure the PHP scripts don't run for longer than 30 secs, unless we use set_time_limit? Is there a way to set the idle timeout on a per script basis (something akin to a set_time_limit?)

Here is our pool configuration:

[www]
user = www-data
group = www-data
listen = /var/run/php5-fpm.sock
listen.owner = www-data
listen.group = www-data
pm = static
pm.max_children = 55
pm.max_requests = 10000

php_value[memory_limit] = 128M
php_value[max_execution_time] = 30
php_value[upload_max_filesize] = 20M
php_value[post_max_size] = 20M
php_value[max_input_vars] = 9999

And here is our fastcgi.conf

<IfModule mod_fastcgi.c>
    AddType application/x-httpd-fastphp5 .php
    Action application/x-httpd-fastphp5 /php5-fcgi
    Alias /php5-fcgi /usr/local/php-5.6.24/sbin/php5-fpm
    FastCgiExternalServer /usr/local/php-5.6.24/sbin/php5-fpm -socket /var/run/php5-fpm.sock -idle-timeout 30 -pass-header Authorization
    <Directory /usr/local/php-5.6.24/sbin/>
        Require all granted
   </Directory>
</IfModule>
Hypertrophy answered 1/11, 2016 at 13:20 Comment(0)
M
27

I have found my self in similar situation with long running processes and php-fpm and fastcgi when migrated from mod_php.

The error you are seeing is from apache's fastcgi proxy who killed connection to php-fpm pool because your script did not outputted anything for 30 seconds.

You can change idle-timeout in your apache config to extend it (cannot be 0):

FastCgiExternalServer /usr/lib/cgi-bin/php7-fcgi -socket /run/php/php7.0-fpm.sock -idle-timeout 1800 -pass-header Authorization

Chain goes like this: Apache -> FastCgiExternalServer proxy -> php-fpm pool server -> php process

Apache proxy kills connection to php, so setting max_execution_time or set_time_limit from php doesn't matter.

AFAIK if php is being run on Apache via mod_fastcgi, there is no way to set per script time limits from php code or .user.ini or via apache (.htaccess). So that means that by extending it in one place you are extending timeout for eg. both your frontend and backend users. Alternatively you could separate it via 2 vhosts and define different timeout values there.

Multivibrator answered 3/1, 2017 at 22:8 Comment(4)
Regarding your comment on mod_fastcgi, could you make the time limits long everywhere, then set the time limit in the application using set_time_limit() to a shorter time, that way the application has more control?Mas
@FrankForte afaik - nope, server settings take precedence over application settings in this case. server will just cut off connection.Multivibrator
Example: server set for 600 second timeout, application set for 30 second, or 300 second timeout - as long as the application timeout is shorter than the server, I imagine the application timeout triggers first (in which case a shutdown function can do some final cleanup before PHP exits).Mas
note that this is for httpd 2.2 solution,, where a 2.4 solution uses the ProxyPassMatch instead, so you have to implement your timeout differently.Flashlight
M
11

While this doesn't necessarily fit the OP's configuration, most people are going to be running PHP-FPM under a proxy setting. As such, you can set the timeout for a proxy setup like so (this is my php.conf)

<Proxy "fcgi://127.0.0.1:9000">
   ProxySet timeout=300
</Proxy>

<FilesMatch \.php$>
    SetHandler application/x-httpd-php
    SetHandler "proxy:fcgi://127.0.0.1:9000"
</FilesMatch>

If you're using a .sock file instead, just replace both instances of fcgi://127.0.0.1:9000 with the command to use the sock file

Mustache answered 19/2, 2018 at 19:59 Comment(1)
I am curious what the benefits and drawbacks are to using Proxy vs socket with proxy disabled.Pinnatipartite

© 2022 - 2024 — McMap. All rights reserved.