简体   繁体   中英

How to deal with PHP-FPM finishing state?

I have a website using NGINX & PHP-FPM. As you may know PHP-FPM has a status page for it's pools with detailed information about it's processes. My problem is that as time passes many processes state become "finishing", and will not change their "finishing" state until I reload PHP-FPM.

The bad thing is that "finishing" processes counts as active processes and when the number of active processes surpass pm.max_children bad things happen on my website.

I know some php-fpm pool parameters to kill idle processes, but I can't find parameters to kill finishing proccesses after a certain amount of time.

How to deal with PHP-FPM finishing state? Is there a configuration parameter to kill these "finishing" processes after some time? Could this be a misconfiguration between NGINX and PHP-FPM? What are the reasons for "finishing" states?

Here is an image of php-fpm status. Reds are finishing states, which is what I'm trying to fix. Request URI are the different pages of my site.

在此输入图像描述

Thanks for your knowledge.

PD1: Right now I'm reloading PHP-FPM every 15 minutes and that "fixes" more or less finishing states... but I think this could be an important performance problem with more traffic.

PD2: Until now the only solution I think could work is to read the php-fpm status page, get all procceses with finishing states and kill proccesses by pid that surpass an arbitrary request duration.

Had the same problem. Here's what I used as a temporary solution:

Create a PHP file with the content:

<?php
fastcgi_finish_request();
?>

edit php.ini:

auto_append_file = /path/to/your/file.php

i had problem like that and this was my fix :

It turns out we were using invalid Memcached keys in certain situations. This was causing Memcached to die without error and the PHP process was staying alive.

https://serverfault.com/questions/626904/php-fpm-state-finishing-but-never-completes

Neither comment solved or explained the root cause behind the issue. Sample code to perform the PD2 approach in killing these processes of should be something like this:

<?php

while (true) {
    $data_json = file_get_contents("http://localhost/fpmstatus?json&full");
    $data = json_decode($data_json, true);

    foreach ($data['processes'] as $proc) {
            if ($proc['state'] === "Finishing") {
                    $pid = $proc['pid'];
                    $duration = $proc['request duration'] / 1000000.0;
                    echo json_encode(compact("pid", "duration"));
                    if ($duration > 60) {
                            passthru("kill -9 " . $pid);
                            echo " KILLED\n";
                    } else {
                            echo "\n";
                    }
            }
    }
    echo count($data['processes']);
    echo "\n";
    sleep(30);
}

When running this code, I did find out that errors like this would occur in the error.log:

2017/08/06 13:46:42 [error] 20#20: *9161 recv() failed (104: Connection reset by peer) while reading response header from upstream, client: 77.88.5.19, server: hostname1, request: "GET /?p=9247 HTTP/1.1", upstream: "fastcgi://uni x:/run/php/php7.0-fpm.sock:", host: "hostname2"

The obvious mismatch was that the request was handled by the block for "hostname1", and a block for "hostname2" didn't exist (anymore). I can't say for sure that it was the reason. There were "finishing" requests even after declaring a server_name _; block, but they were less frequent than anything that was going on before that.

My server had the enablereuse=on setting in the apache proxy configuration. Removing this fixed the "Finishing" problem.

Also listed in the question: https://serverfault.com/questions/626904/php-fpm-state-finishing-but-never-completes

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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