Skip to content

Instantly share code, notes, and snippets.

@mttjohnson
Created March 30, 2023 20:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mttjohnson/48720d8a3b19a799c6233594ce1cc84e to your computer and use it in GitHub Desktop.
Save mttjohnson/48720d8a3b19a799c6233594ce1cc84e to your computer and use it in GitHub Desktop.
Reloading PHP-FPM and Watching Processes

Monitor php-fpm processes

This shows the master processes and 1 child from each pool and refreshes every 5 seconds

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

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:

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:

sudo systemctl reload php7.0-fpm.service

If you are using supervisord you could utilize supervisorctl to accomplish this similarly.

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:

# 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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment