Open misog opened 5 years ago
if you have 20 Laravel apps on one server with one vCPU it all takes 100% of CPU every minute
This is an infrastructure problem, not a framework issue.
Most people will run <10 apps on a single app server. And fewer for each large-scale/resource-intensive application.
The only situation I can imagine running 20+ sites from one server is a clients/staging server so my clients can see drafts of sites. But I wouldn't run schedules or anything on them anyways.
If you're looking for a slim framework that can handle running 20+ apps on a $5 DO droplet, you'll probably want to look at PHP Slim or something.
This indeed infrastructural. If you don't do anything in your schedule, the CPU most likely won't peek. It probably just peeks because you are doing some work in there.
However here's an idea for a workaround: You can just add a sleep $someSeconds &&
in front of your command where you execute the schedule:run
command. Put in some different values for the $someSeconds
placeholder and this should ensure that they won't run in a parallel manner.
Another idea would be to put all your schedule:run
calls in a shell script where each command gets executed after the other one has been completed. Then just call that shell script in your crontab.
Further to what @thannaske said, you can also set your schedule to not overlap executions of certain commands.
When defining your schedules, tag on ->withoutOverlapping()
and it will only process one instance of a particular command at any given moment. This is slower, but better optimised for lower available resources.
Docs: https://laravel.com/docs/5.8/scheduling#preventing-task-overlaps
The problem is not my custom code, but that even empty Console\Kernel.php instance takes 20 * 4% CPU.
I implemented simple custom schedule checker in artisan
file which decides if to exit the script. It decreased the average CPU load to 2-3% per one process. Then I delayed CRON as @thannaske mentioned, with a random delay. This should be good for tens of new applications.
* * * * * sleep $(awk "BEGIN {print $(shuf -i 0-10000 -n 1) / 1000}") && artisan-cron schedule:run >> /dev/null 2>&1
empty Console\Kernel.php instance takes 20 * 4% CPU.
…
I implemented simple custom schedule checker in artisan file which decides
Seems like that the booting of the framework itself is slow? Did you investigate further?
There's https://github.com/laravel/ideas/issues/1399 , maybe it's related.
@mfn yes, the booting is slow because the artisan file loads a lot of the framework, that is why I proposed to create a new file laravel-cron-scheduler which would be CPU efficient and would run only necessary classes.
Hi, I am using Laravel 5.6 on DigitalOcean with one vCPU, however this is probably an issue for higher Laravel versions too.
The schedule:run command is expected to be called in CRON. You can not control at which second the command is called.
This creates a big problem when you have multiple apps on one VPS or cloud server - each artisan:run (without any application code) takes 4% - 5% of CPU power (measured with htop) and if you have 20 Laravel apps on one server with one vCPU it all takes 100% of CPU every minute. Sure, it is at a peek just for a second but it can create problems with Varnish cache timeouts.
My proposal is to create a new file
laravel-cron-scheduler
which would be CPU efficient as an alternative to the slowartisan
file.