## Monitor php-fpm processes This shows the master processes and 1 child from each pool and refreshes every 5 seconds ```bash WATCH_COMMAND=$(cat <<'COMMAND_CONTENT' sudo ps afxo pid,user,command --sort command | perl -ne 'print if /^\s*$/ || /^\s*\d+(.+)$/ && ! $SEEN{$1}++' | grep -i '[p]hp-fpm' COMMAND_CONTENT ) watch -n 5 "${WATCH_COMMAND}" ``` ## Listing PHP-FPM Process Summary List php-fpm processes showing process IDs and remove duplicate process commands ```bash sudo ps afxo pid,user,command --sort command \ | perl -ne 'print if /^\s*$/ || /^\s*\d+(.+)$/ && ! $SEEN{$1}++' \ | grep -i '[p]hp-fpm' ``` `ps afxo pid,user,command --sort command` will give us a nice tree structure showing parent/child process relationships, and allows us to specify the fields we want to output `pid,user,command` and then sorts everything by the command being executed `--sort command` which makes it easier to have consistent comparisons. `perl -ne 'print if /^\s*$/ || /^\s*\d+(.+)$/ && ! $SEEN{$1}++'` is a perl one liner that primarily removes partially duplicate lines without changing the order of any of the output. `/^\s*\d+(.+)$/` just does a match and perl will output the while line if it finds a match, but only if `! $SEEN{$1}++` also evaluates to be true `! $SEEN{$1}++` is taking the first capture group `$1` from the regex `(.+)` and using that as a key in the %SEEN hash while also incrementing a count of how many times that portion of the line was seen. Since the regex capture group is only matching a portion of the line I can remove any lines where that specific portion of the line is the same. `grep -i '[p]hp-fpm'` just filters the output of the process list to only show me lines containing `php-fpm` and uses a regex pattern `[p]` which just patches a `p` to help exclude the grep command from getting matched. ## Building/Debugging Partial Duplicate Matches For building and debugging a pattern match of duplicate portions of lines you may want to see what is getting matched, so you could perform a regex substitution `s/^\s*\d+(.+)$/$1/` instead of a match allowing the capture group to be printed instead of the original line like this: ```bash sudo ps afxo pid,user,command --sort command \ | perl -ne 'print if /^\s*$/ || s/^\s*\d+(.+)$/$1/ && ! $SEEN{$1}++' \ | grep -i '[p]hp-fpm' ``` ## Graceful Reload of PHP-FPM For a graceful reload of php-fpm we can send a signal to the master process. SIGUSR2 will cause a graceful reload of all workers and reload the fpm config/binary. If the service is being managed by systemd this is likely part of the service script and you could reload it like this: ```bash sudo systemctl reload php7.0-fpm.service ``` If you are using `supervisord` you could utilize `supervisorctl` to accomplish this similarly. ```bash sudo supervisorctl pid phpfpm | sudo xargs kill -USR2 # or sudo supervisorctl signal USR2 phpfpm ``` To see what happens during this reload you can watch some of the worker processes recyle this way: ```bash # List php-fpm processes showing process IDs and remove duplicate process commands function phpfpm_processes { sudo ps afxo pid,user,command --sort command | perl -ne 'print if /^\s*$/ || /^\s*\d+(.+)$/ && ! $SEEN{$1}++' | grep -i '[p]hp-fpm' } sudo supervisorctl signal USR2 phpfpm for i in {1..30}; do phpfpm_processes; sleep 0.1; done ```