Search code examples
phpphp-7.2fedora-29

PHP-FPM not responding when CPU is 100% in low priority processes


I'm having a problem when CPU is 100% usage: PHP-FPM does not respond, even the processes using 100% of CPU are running in lowest priority (+19).

Let me explain: my site triggers an audio converter (ffmpeg) using inotify + a bash script. The converter is running using "nice -n 19". So, CPU usage is 100% but, in theory, PHP-FPM has priority (default 0 priority).

What happens: only PHP freezes. Apache can respond to files like JPG/CSS/JS. Linux stable, other SWs too. All .php returns "504 Gateway Timeout" (browser, Apache response). Apache opens a lot of php-fpm instances and keep them open.

30585 fedora    19   0.0   0.3   0:00.00 snippeter
30586 fedora    19  25.0   2.8   0:00.10 ffmpeg

15640 fedora     0   0.0   1.0   0:00.12 php-fpm
17174 fedora     0   0.0   1.0   0:00.10 php-fpm
20583 fedora     0   0.0   0.9   0:00.00 php-fpm
21072 fedora     0   0.0   0.9   0:00.00 php-fpm
21309 fedora     0   0.0   0.9   0:00.00 php-fpm
22601 fedora     0   0.0   0.9   0:00.00 php-fpm
23172 fedora     0   0.0   0.9   0:00.00 php-fpm
23277 fedora     0   0.0   0.9   0:00.00 php-fpm
24170 fedora     0   0.0   0.9   0:00.00 php-fpm
24823 fedora     0   0.0   0.9   0:00.00 php-fpm
24916 fedora     0   0.0   0.9   0:00.00 php-fpm
26589 fedora     0   0.0   0.9   0:00.00 php-fpm

%Cpu(s):  8.5 us,  4.5 sy, 85.6 ni,  0.0 id,  0.5 wa,  1.0 hi,  0.0 si,  0.0 st

Changing php-fpm priority (renice), no difference.

I don't know what to do... I want to run processes in background, even using 100% of CPU, but keeps PHP+Apache running normally.

Server: Fedora 29, PHP 7.2.


Solution

  • Found a solution!

    The problem is not related to 100% CPU usage, or just one CPU. Since I have a loop to open each audio converter (bash file), and wait it to finish to run the next one, the PHP session is locked! So, when another PHP script, in the same session, try to execute, it cannot read the session file, so, PHP freezes (waiting to have access to the session file, until a "Gateway Timeout" error). That's why only PHP freezes, not other softwares.

    To fix, I had to run this before the main loop:

    session_write_close();
    session_start(['read_and_close'=>true]);
    

    So, it writes and closes the session file, and read it again once, without locking it.

    This only works in PHP 7+ and, obviously, you cannot write any session data. Or, after the loop, just open the session again with session_start().