Multiple queue workers: some restart, some don't with ERROR (spawn error) - laravel-5

Our application provides a separate database for each of our users. I have set up an emailing job which users may dispatch to run in background via a Laravel 5.3 Queue. Some users succeed in evoking this facility (so it does work - same codebase) but some users fail.
The users who fail to generate the email are all characterised by the following error when trying to restart all user queues using sudo supervisor start all, eg:
shenstone-worker:shenstone-worker_02: ERROR (spawn error)
shenstone-worker:shenstone-worker_00: ERROR (spawn error)
shenstone-worker:shenstone-worker_01: ERROR (spawn error)
An example of a user who's email facility works:
meadowwood-worker:meadowwood-worker_02: started
meadowwood-worker:meadowwood-worker_00: started
meadowwood-worker:meadowwood-worker_01: started
The log of all attempted restarts has a load of these spawn errors at the beginning then all the successful queue restarts at the end.
The worker config files for these two users are:
[program:shenstone-worker]
process_name=%(program_name)s_%(process_num)02d
directory=/var/www/solar3/current
environment=APP_ENV="shenstone"
command=php artisan queue:work --tries=1 --timeout=300
autostart=true
autorestart=true
user=root
numprocs=3
redirect_stderr=true
stdout-logfiles=/var/www/solar3/storage/logs/shenstone-worker.log
and
[program:meadowwood-worker]
process_name=%(program_name)s_%(process_num)02d
directory=/var/www/solar3/current
environment=APP_ENV="meadowwood"
command=php artisan queue:work --tries=1 --timeout=300
autostart=true
autorestart=true
user=root
numprocs=3
redirect_stderr=true
stdout-logfiles=/var/www/solar3/storage/logs/meadowwood-worker.log
As you see, generically identical. Yet shenstone does not restart its queues to capture requests from its jobs table, but meadowwood does. No logfiles appear in storage.
So why do some of these queues restart successfully, and a load don't?
Looking at the stackoverflow issue Running multiple Laravel queue workers using Supervisor inspired me to run sudo supervisorctl status and yes I can see a more elaborate explanation of my problem:
shenstone-worker:shenstone-worker_00 FATAL too many open files to spawn 'shenstone-worker_00'
shenstone-worker:shenstone-worker_01 FATAL too many open files to spawn 'shenstone-worker_01'
shenstone-worker:shenstone-worker_02 FATAL too many open files to spawn 'shenstone-worker_02'
As opposed to:
meadowwood-worker:meadowwood-worker_00 RUNNING pid 32459, uptime 0:51:52
meadowwood-worker:meadowwood-worker_01 RUNNING pid 32460, uptime 0:51:52
meadowwood-worker:meadowwood-worker_02 RUNNING pid 32457, uptime 0:51:52
But I still cannot see what I can do to resolve the issue.

If you haven't come up with any other ideas, increasing the limit of open files in your server might help, maybe. Check this for instance
https://unix.stackexchange.com/questions/8945/how-can-i-increase-open-files-limit-for-all-processes
However, having many files open might affect the performance of your system and you should check why is it happening and prevent if you can.

Thanks Armando.
Yes, you’re right: open files is the issue. I did a blitz on the server to increase these, but ran into problems with MySQL, so I backed out my config changes.
We host over 200 customers ech with their own .env. Each of these have their own workers.
I’ll revisit the problem sometime.

Related

Laravel systemd queue job stops, when using restart=on-failure

We have a Laravel SystemD job for the queue, which for example sends out notification email.
Now we noticed, that the SystemD job is stopped when a email delivery did not work.
This is how our service definition looks like:
/etc/systemd/system # cat example.com-queue.service
[Unit]
Description=Laravel queue worker
[Service]
User=www-data
Group=www-data
Restart=on-failure
ExecStart=/usr/bin/php /var/www/html/example.com/web/artisan queue:work --daemon
[Install]
WantedBy=multi-user.target
The website https://www.freedesktop.org/software/systemd/man/systemd.service.html#Restart= states, that on-failure does not restart "on success".
If we look closer at the service state, we see that the Laravel Queue is actually exiting with a "0" exit code:
# systemctl status example.com-queue.service
● example.com-queue.service - Laravel queue worker
Loaded: loaded (/etc/systemd/system/example.com-queue.service; enabled; vendor preset: enabled)
Active: inactive (dead) since Sat 2021-08-14 15:11:18 CEST; 2 days ago
Process: 2417820 ExecStart=/usr/bin/php /var/www/html/example.com/web/artisan queue:work --daemon (code=exited, status=0/SUCCESS)
Aug 14 15:11:08 example php[2417820]: [2021-08-14 15:11:08][16768] Processing: App\Notifications\UploadSuccess
Aug 14 15:11:18 example php[2417820]: [2021-08-14 15:11:18][16768] Failed: App\Notifications\UploadSuccess
Aug 14 15:11:18 example systemd[1]: example.com-queue.service: Succeeded.
There is a easy fix: We could switch to "Restart=always", but I want to shed light on the fact and find out why Laravel - in case of an error - returns a zero exit code. Also we are afraid that "Restart=always" might cause unwanted side effects.
Usually, I use supervisor to handle queues. However, it's very advanced, and there are many article/support published on its configuration, and you can find them easily.
I'm following this supervisor configuration in the Laravel article
That's perfectly worked for me, and I've configured a lot of Laravel-projects queues by it. It also has many built-in options to handle queue-failure, restarting etc. Moreover, We can run multiple workers using it easily in minimum time. Its process handling approach is very optimized and well documented.
Basic Installation process:
Manage Laravel queues or any managed process which needs to be run on the server
sudo apt-get install supervisor
load directory cd /etc/supervisor/conf.d and create a configuration file my-project-worker.conf and add the following configurations
[program:<custom-worker-name>]
command=<project-directory-path>/artisan queue:work --tries=3 --sleep=3
directory=<project-directory-path i.e /var/www/html/example-project>
stdout_logfile=<custom-path-to-store-log i.e /var/www/html/example-project/storage/logs/supervisord.log>
redirect_stderr=true
autostart=true
autorestart=true
numprocs=1
stopwaitsecs=3600
## For Multiple Workers ##
[program:%(<custom-worker-name>)s_%(process_num)02d]
command=<project-directory-path>/artisan queue:work --tries=3 --sleep=3
directory=<project-directory-path i.e /var/www/html/example-project>
stdout_logfile=<custom-path-to-store-log i.e /var/www/html/example-project/storage/logs/supervisord.log>
redirect_stderr=true
autostart=true
autorestart=true
numprocs=3
stopwaitsecs=3600
Note: Make sure set <custom-worker-name>, <project-directory-path> and <custom-path-to-store-log> according to your project.
Remember that when you deploy new code which contains modifications to existing job code, you need to restart the supervisor process or that particular job.
sudo supervisorctl reread
sudo supervisorctl update
sudo supervisorctl start <custom-worker-name>:*
To check running supervisor processes:
sudo supervisorctl
To check the status of the process:
sudo systemctl status supervisor
To stop the process:
sudo systemctl stop supervisor

Stopping a Laravel Queue after it has finished running

I am running a web application on Laravel 5.5. I have a requirement to run the jobs in a queue and then stop the queue. The queue cannot be allowed to stay running.
I am running the below command but this just endlessly carries on.
php artisan queue:work --tries=3
If I use supervisord can I stop the queue from inside the Laravel application.
Any help is really appreciated.
From the documentation:
Processing All Queued Jobs & Then Exiting The --stop-when-empty option may be used to instruct the worker to process all jobs and then exit gracefully. This option can be useful when working Laravel queues within a Docker container if you wish to shutdown the container after the queue is empty:
Try php artisan queue:work --tries=3 --stop-when-empty
https://laravel.com/docs/8.x/queues#running-the-queue-worker

Laravel - websockets supervisor run error

I´ve been searching but all the answers i found didn´t resolve my problem, my system is centOS and i have followed this instructions with no luck, after that i saw other links, but at some point i´m confused and don´t know what is wrong anymore, so below is what i have done and hopping someone could help me out:
As the instructions say i went to /etc/supervisord.d and created a file called websockets.conf, inside i did this:
[program:websockets]
command=/usr/bin/php /home/gynkgo/artisan websockets:serve
numprocs=1
autostart=true
autorestart=true
user=root
After that, i did the supervisorctl update and then supervisorctl start websockets this last one returns: websockets: ERROR (no such process). This was when i satrted digging for some other solutions and found this so i went to /etc/supervisord.conf, edit the file i putted what is below:(the last version of what i tried)
[program:websockets]
process_name=%(program_name)s_%(process_num)02d
command=php /home/gynkgo/artisan websockets:serve
autostart=true
autorestart=true
user=root
numprocs=3
redirect_stderr=true
but still no luck at all, what am i missing? som epeople say i should have a /etc/supervisor directory but i don´t think that´s the solution, others say that that´s not needed.
Thanks for your time
Regards
EDIT:
After a few tries, i did this supervisorctl status and i can see the below:
websockets:websockets_00 RUNNING pid 5137, uptime 0:04:23
but when i go to my app i see the error:
WebSocket connection to (not relevant) failed: Error during WebSocket handshake: Unexpected response code: 503
The error above normally disapears if i do php artisan websockets:serve --port=6002, BUT this is the way to force the websockets start, i need the supervisor in order not to do this as you already know.

Laravel 5.6 queue restart CPU usage

I installed my Laravel 5.6 application on shared hosting service. But my hosting company is not happy with the CPU usage of my application. This high CPU usage shows up when killing the queue worker, no matter whether I kill the worker manually or via a cron job.
Can someone explain me why this 'php artisan queue:restart' takes so much CPU time? And if possible, how can I reduce?
Restart:
cd /home/xxxxxx/rdw_laravel/; /usr/local/bin/php72 artisan queue:restart >/dev/null 2>&1
Activate queue worker:
cd /home/xxxxxx/rdw_laravel/; /usr/local/bin/php72 artisan queue:work --daemon
You seem to have memory leaks so read up on memory.
Straight from the documentation on how to run queue worker:
Daemon queue workers do not "reboot" the framework before processing each job. Therefore, you should free any heavy resources after each job completes. For example, if you are doing image manipulation with the GD library, you should free the memory with imagedestroy when you are done.
Alternative is to use queue:listen instead, the difference is that :work boots up once and runs forever, while :listen boots up before each job.
Note: queue:work and queue:work --daemon is equal so you do not have to run cron with the --daemon flag.
Note: Why do you run :restart so often? I doubt that you update your code every day, so use :restart only when you update the code.
Related
What is the difference between queue:work --daemon and queue:listen

Laravel jobs leaves an idle postgresql process on DEALLOCATE

Every time a Delayed Job is has run on my server I can see a new idle process in postgreSQL. Running select * from pg_stat_activity; I can see:
DEALLOCATE pdo_stmt_00000018
I tried to understand, and one more line (and one more process in htop) appears each time a delayed queued job had just ran.
The last line of my Job is:
$this->log->info("Invitation {$this->invitation->uuid} sent");
And I can see this in my logs, so everything is alright BUT it does not clean up after. I have a idle process every time with "DEALLOCATE pdo_stmt_00000xxx".
What can I do to avoid this problem? What is causing this?
Here is my supervisor config:
[program:laravel-queue-worker]
process_name=%(program_name)s_%(process_num)02d
command=php /path/to/my/site/artisan queue:work --queue=invitation,default --sleep=3 --tries=3
autostart=true
autorestart=true
user=www-data
numprocs=2
redirect_stderr=true
stdout_logfile=/path/to/my/logs/worker.log
Side note: the idle processes disappear when I run php artisan queue:restart
I found a (quick and dirty) workaround. Adding this at the end of my Job handle function:
\DB::disconnect();
sleep(1);
A issue has been opened on Laravel: https://github.com/laravel/framework/issues/18384

Resources