How to Use the supervisor to guard the main php-fpm process for Automatic Restart of php-fpm, supervisorphp-fpm
Recently, a colleague has a monitoring requirement for the php-fpm process, that is, if the master process of the php-fpm unexpectedly exits (may be crash or killed by mistake ), we hope that the master process can be automatically started to avoid service interruption.
As we know, the supervisor is a very powerful Process Monitoring (monitor & control) tool, which can theoretically implement the daemon needs of the php-fpm master process. Therefore, I helped my colleagues test how to use the supervisor to fulfill their needs. The result shows that the supervisor is indeed an artifact and can solve the problem with a reasonable configuration file.
The following is my survey process and configuration file that ultimately implements the php-fpm main process daemon function. Here we will make a record and hope to help others.
1. Install supervisor
The supervisor is implemented in python and is in the research phase. Therefore, create a new virtualenv environment and install the supervisor package with pip.
Now, the basic survey environment has been set up. Of course, the php-fpm and PHP environments and front-end Nginx have long been ready.
2. Analyze the php-fpm.sh script
After compiling and installing PHP, the php-fpm binary C program will also be compiled and installed. The typical path is in the php_install_path/sbin/directory. There is also a script named php-fpm.sh under the directory to control the start/stop/restart/reload actions of the php-fpm process.
./Sbin/php-fpm.sh script, the "start" operation started the php-fpm main process, the rest of the operations are achieved by sending signal to the php-fpm master process.
# Code segment in php-fpm.shcase "$1" in start) echo-n "Starting php-fpm" # the following line is the key command $ php_fpm_BIN -- daemonize $ php_opts if ["$? "! = 0]; then echo "failed" exit 1 fi wait_for_pid created $ php_fpm_PID if [-n "$ try"]; then echo "failed" exit 1 else echo "done" fi ;;
Input from the terminal ". /sbin/php-fpm.sh start ", the actual execution of the code, you can see that the php-fpm process startup parameter is-daemonize $ php_opts, the value of $ php_opts is "-fpm-config $ php_fpm_CONF-pid $ php_fpm_PID ".
Note:: When the php-fpm.sh starts the php-fpm master process, the daemonize parameter is passed in, indicating that the php-fpm master process is started in daemon mode,When a process is monitored by a supervisor, the monitored process cannot be a daemon process.This is because the daemon usually causes the parent process to "end its life" after fork completes the child process, that is, the parent process created by the supervisor exits, the supervisor cannot monitor the child processes created by the exited process. For more information about daemon process, see Linux Daemon Writing HOWTO.
According to the above analysis, we know that as long as the supervisor starts the php-fpm process, the daemonize parameter is not passed in.
3. The supervisor configuration file that implements the php-fpm main process daemon Function
The above analysis tells us how to solve the problem. The following describes how to verify the available configuration file. The file is located under the php-fpm.conf peer directory (the typical path is php_install_path/etc /).
[inet_http_server] ; inet (TCP) server disabled by defaultport=127.0.0.1:9015 ; (ip_address:port specifier, *:port for all iface)[supervisord]logfile=./var/log/supervisord.log ; (main log file;default $CWD/supervisord.log)logfile_maxbytes=50MB ; (max main logfile bytes b4 rotation;default 50MB)logfile_backups=2 ; (num of main logfile rotation backups;default 10)loglevel=info ; (log level;default info; others: debug,warn,trace)pidfile=./var/run/supervisord.pid ; (supervisord pidfile;default supervisord.pid)nodaemon=false ; (start in foreground if true;default false)minfds=1024 ; (min. avail startup file descriptors;default 1024)minprocs=200 ; (min. avail process descriptors;default 200)identifier=sup.php-fpm ; (supervisord identifier, default is 'supervisor')[rpcinterface:supervisor]supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface[supervisorctl]serverurl=http://127.0.0.1:9015 ; use an http:// url to specify an inet socket[program:php-fpm]command=bash -c "sleep 1 && /home/slvher/tools/php/5.6.11/sbin/php-fpm --fpm-config /home/slvher/tools/php/5.6.11/etc/php-fpm.conf --pid /home/slvher/tools/php/5.6.11/var/run/php-fpm.pid" ; the program (relative uses PATH, can take args)process_name=%(program_name)s ; process_name expr (default %(program_name)s)autostart=true ; start at supervisord start (default: true)autorestart=true ; whether/when to restart (default: unexpected)startretries=5 ; max # of serial start failures (default 3)exitcodes=0,2,70 ; 'expected' exit codes for process (default 0,2)stopsignal=QUIT ; signal used to kill process (default TERM)stopwaitsecs=2 ; max num secs to wait b4 SIGKILL (default 10)
The configuration file structure is easy to grasp by viewing the supervisor documentation,Pay special attention to the two configuration items.:
1) command
It specifies the startup command of the process to be monitored by the supervisor. As you can see, here we didn't pass the daemonize parameter to php-fpm, And the other parameters only expand the shell variable in the php-fpm.sh.
We have noticed that command does not directly call php-fpm, but executes two commands through bash-c,The first command is sleep 1.. This is because the port occupied by the php-fpm after the stop is usually not immediately released. At this time, when the supervisor tries to pull the process again at an extremely fast speed, the following error may cause multiple retries to fail:
## var/log/php-fpm.error.log[18-Jul-2015 21:35:28] ERROR: unable to bind listening socket for address '127.0.0.1:9002': Address already in use (98)[18-Jul-2015 21:35:28] ERROR: FPM initialization failed
The supervisor does not currently support the delay restart function. Therefore, the problem can only be solved through a slightly tricky method that runs sleep first and then starts again. The results show that the effect is good and there are no side effects. -_-
2) autorestart
The document description is as follows:
May be one of false, unexpected, or true. If false, the process will never be autorestarted. If unexpected, the process will be restart when the program exits with an exit code that is not one of the exit codes associated with this process’ configuration (see exitcodes). If true, the process will be unconditionally restarted when it exits, without regard to its exit code.
The default value is unexpected, indicating that if the exit code of the monitored process is abnormal, the supervisor will restart the process. This parameter is set to true, indicating that the process will be pulled up again when it exits.
After this configuration, run the following command in the virtualenv environment established in step 1 of this article to monitor the php-fpm master process by the supervisor:
shell> supervisord -c etc/sup.php-fpm.conf
Then, we can see through ps x | fgrep fpm that the main php-fpm process has been pulled up.
Kill the main php-fpm process and run ps x | fgrep fpm again. A new main php-fpm process is created by the supervisor.
So far, the need to use the supervisor to guard the main php-fpm process to automatically restart php-fpm has been solved.
References
====================================== EOF ======================== ======
Copyright Disclaimer: This article is an original article by the blogger and cannot be reproduced without the permission of the blogger.