In production, we need a way to keep our queue:work
processes running. A queue:work
process may stop running for a variety of reasons, such as an exceeded worker timeout or the execution of the queue:restart
command.
For this reason, we need to configure a process monitor that can detect when processes like queue:work
stop running and restart them. Supervisor is a process monitor commonly used in Linux environments and we will discuss how to configure it.
This chapter will cover Debian-based (Ubuntu) and RedHat-based (Fedora) Linux distributions.
To install Supervisor you may use the following command:
sudo apt-get install supervisor
sudo dnf install supervisor
Make sure the Supervisor itself is started during system boot and start it if it is not started by default after installation.
sudo systemctl enable supervisorsudo systemctl start supervisor
Now let's create a new configuration file for the Supervisor. Different distributions have a bit different configuration locations.
On Ubuntu Supervisor configurations follows this mask:
/etc/supervisor/conf.d/*.conf
Create /etc/supervisor/conf.d/laravel-worker.conf file.
On Fedora Supervisor configurations follows this mask:
/etc/supervisord.d/*.ini
Create /etc/supervisord.d/laravel-worker.ini file.
While having different Supervisor configuration locations on both distros contents of the configuration itself doesn't differ since it is the same service.
[program:laravel-worker]directory=/home/web/laravel-queuescommand=php artisan queue:work --sleep=1 --tries=3 --max-time=3600 process_name=%(program_name)s_%(process_num)02dautostart=trueautorestart=truestopasgroup=truekillasgroup=trueuser=webnumprocs=8redirect_stderr=truestdout_logfile=/home/web/.supervisor/laravel-worker.logstopwaitsecs=3600
You may rename the process to something else by changing [program:laravel-worker]
to [program:my-meaningful-name]
.
Also, you should update the command
, user
, numprocs
, and stdout_logfile
flags to match your environment and requirements.
Now let's run through all the settings:
directory
- a file path representing a directory to which supervisord should temporarily chdir before exec'ing the childcommand
- actual command to launch queue workers including full path to your project and additional flags for workersprocess_name
- this flag defines how your processes are displayed when you run supervisorctl status
commandautostart
- If true, this program (command) will start automatically when the supervisord is startedautorestart
- Specifies if supervisord should automatically restart a process if it exits when it is in the RUNNING
state.stopasgroup
- If true, the flag causes the Supervisor to send the stop signal to the whole process group. This is useful for programs that do not propagate stop signals to their children, leaving them orphaned.killasgroup
- If true, when resorting to SIGKILL to the program to terminate it send it to its whole process group instead, taking care of its children as well.user
- Instruct the supervisord to use this UNIX user account as the account which runs the program. Usually, you want to run command
under the same user
as your Laravel application runs.numprocs
- Supervisor will start as many instances of this program as named by numprocs.redirect_stderr
- If true, cause the process' STDERR output to be sent back to supervisord on its STDOUT file descriptor.stdout_logfile
- Put process output in this file. Since workers will be running in the background sometimes it is useful to have logs which you would usually see in the terminal when running queue:work
manually.stopwaitsecs
- The number of seconds to wait for the OS to return a SIGCHLD to supervisord after the program has been sent a stopsignal. If this number of seconds elapses before the supervisord receives a SIGCHLD from the process, the supervisord will attempt to kill it with a final SIGKILL.You should ensure that the value of
stopwaitsecs
is not less that the number of seconds consumed by your longest-running job. Otherwise, Supervisor may kill the job before it is finished processing.
Once the configuration file has been saved reload the daemon's configuration files without affecting currently running processes using the following command:
sudo supervisorctl reread
If reread was successful and no errors have been reported you can reread them but this time forcing updates to processes using this command:
sudo supervisorctl update
Alternatively, you can run the supervisorctl start program-name:*
command to only start processes if it was read earlier:
sudo supervisorctl start laravel-worker:*
And then check what processes are running by Supervisor:
sudo supervisorctl status
Should give similar output depending on your configuration.
laravel-worker:laravel-worker_00 RUNNING pid 612470, uptime 0:00:22laravel-worker:laravel-worker_01 RUNNING pid 612471, uptime 0:00:22laravel-worker:laravel-worker_02 RUNNING pid 612472, uptime 0:00:22laravel-worker:laravel-worker_03 RUNNING pid 612473, uptime 0:00:22laravel-worker:laravel-worker_04 RUNNING pid 612474, uptime 0:00:22laravel-worker:laravel-worker_05 RUNNING pid 612475, uptime 0:00:22laravel-worker:laravel-worker_06 RUNNING pid 612476, uptime 0:00:22laravel-worker:laravel-worker_07 RUNNING pid 612477, uptime 0:00:22
Now try registering a new user again on your laravel application, and the email should arrive in the testing inbox.
Before we move on to the next chapter we can stop these workers for now.
To do that run the supervisorctl stop program-name:*
command. For example:
sudo supervisorctl stop laravel-worker:*
laravel-worker:laravel-worker_00: stoppedlaravel-worker:laravel-worker_01: stoppedlaravel-worker:laravel-worker_02: stoppedlaravel-worker:laravel-worker_03: stoppedlaravel-worker:laravel-worker_04: stoppedlaravel-worker:laravel-worker_05: stoppedlaravel-worker:laravel-worker_06: stoppedlaravel-worker:laravel-worker_07: stopped