Closed clemask closed 8 months ago
Feel free to work on it! š
Octane is a great project that is pushing Laravel in a new direction in the realm of the internet, making Laravel more powerful. However, there seem to be some issues with the way it's being handled in certain aspects. Octane's support for Swoole has excited many developers, including myself, envisioning a strong combination of Laravel's ecosystem with Swoole's coroutine advantages.
One crucial point that is not clearly stated in the official documentation is the inability to use Swoole's coroutine. This omission is significant because developers might unknowingly configure coroutine parameters, expecting Octane to work seamlessly with Swoole's coroutine features. However, Octane does not disable the creation of Swoole services with coroutine parameters, leading to subtle issues in the production environment. Problems like network connections being used by other coroutines and issues with Monolog log cycling detection can arise. In the end, developers are forced to disable coroutines as a quick solution, which is a severe incident.
I hope the official team promptly considers adding coroutine support to their roadmap. It's a fantastic feature that not only enhances Laravel but is also crucial for the broader PHP ecosystem.
I hope the official team promptly considers adding coroutine support to their roadmap.
This isn't a trivial thing to do. Right now we don't have the time to work on this ourselves but we'd love to see PR's kickstarting this.
Hey @driesvints, are you familiar with @themsaid's talk from Laracon 2021 on how Swoole coroutines could be integrated into Octane? This is the timestamp: https://youtu.be/-l8o4KMaS4c?feature=shared&t=1792
That change has already been merged into Swoole core: https://github.com/swoole/swoole-src/pull/4330
I'm not sure how difficult it would be to implement, but it'd increase Laravel's performance by a whole order of magnitude.
Welcoming prs š
If you want octane to support coroutine, you must first make database, redis, etc. support connection pooling.
I guess the problem is Laravel supports a lot of DB and cache backends and itād be hard to implement pooling for them allā¦
@taylorotwell @driesvints @nunomaduro Would the core team be interested in having pooling for a select few drivers? Maybe just MySQL and Redis to start. Itād mean coroutines could only be enabled when using those drivers, but Hyperf can handle 100k req/second. Even if coroutines āonlyā bumped Laravelās concurrency to 10k-20k, thatād be nuts and create some serious buzz. Thatās faster than Nodeā¦
FYI @huangdijia is a key Hyperf contributor: https://github.com/hyperf/hyperf/commits/master. He might be willing to help if you guys want to move ahead.
@binaryfire I review all PRs - merging just depends on added complexity / maintenance burden. š
It would be amazing feature for highload apps!
Can this be related? š
Can this be related? š
No thatās not related. Running a few tasks concurrently is different to workers that can properly handle multiple requests per second, which requires db connection pooling etc. I donāt think thereās much interest from the core team in increasing Laravelās performance beyond the current Octane implementation, which only helps by keeping the app booted in memory. It doesnāt use Swoole coroutines at all.
If you want to handle 40k - 100k req/s in real life workloads instead of Octaneās 500-ish, youāll need to either run a bunch of Octane instances behind a load balancer, or look at a proper coroutine framework like Hyperf. The performance difference is night and day.
People who say ~500 req/s is enough just arenāt building certain kinds of apps. Eg. a log ingestion app, API gateways etc. Even a core team member has written articles about adding Go to a Laravel app stack to handle endpoints which receive high numbers of requests, which clearly demonstrates Laravelās performance limitations.
Shipping more features seems to be a higher priority than a major upgrade to performance. This kind of change, and the refactoring that would be required (eg. adding db connection pooling) wonāt ever come from a third party PR. It would need be be driven by the core team.
Hyperf is heavily inspired by Laravel so there are plenty of code references there the core team could look at.
Can this be related? š
No thatās not related. Running a few tasks concurrently is different to workers that can properly handle multiple requests per second, db connection pooling etc. I donāt think thereās much interest from the core team in increasing Laravelās performance beyond Octane, which only helps by keeping the app booted in memory.
So if you want to handle 40k - 100k req/s in real life workloads instead of Octaneās 500-ish, youāll need to either run a bunch of Octane instances behind a load balancer, or look at a PHP framework like Hyperf.
People who say 500 req/s is enough just arenāt building certain kinds of apps. Eg. a log ingestion app, an API gateway etc. Even a member of the core team has written articles about adding Go to a Laravel app stack to handle endpoints which receive high numbers of requests, which is saying something.
Shipping more features seems to be a higher priority than any major upgrades to performance. This kind of change and the refactoring (eg. adding db connection pooling) wonāt come from a third party PR. It would need be be driven by the core team.
The design idea of octane is still based on fpm,To get better performance, you need to redesign
Managed to get Laravel working with multiple Swoole coroutines in one process today. I still have allot of cleaning up to do before a PR, but I am confident it could be ok. Currently we got it working for a custom Kernel that processes sqs jobs for aws lambda, but to get it working for the http kernel is trivial. By Friday, I'll have it up and running in multiple processes as well (probably already works, but needs further testing).
@taylorotwell , @nunomaduro , is this still of interest?
Managed to get Laravel working with multiple Swoole coroutines in one process today. I still have allot of cleaning up to do before a PR, but I am confident it could be ok. Currently we got it working for a custom Kernel that processes sqs jobs for aws lambda, but to get it working for the http kernel is trivial. By Friday, I'll have it up and running in multiple processes as well (probably already works, but needs further testing).
@taylorotwell , @nunomaduro , is this still of interest?
This will be the most long-awaited and amazing feature for all highload Laravel projects!
This kind of change, and the refactoring that would be required (eg. adding db connection pooling) wonāt ever come from a third party PR. It would need be be driven by the core team.
Interestingly enough I did run into this today with testing multiple processes with multiple coroutines each. Database pooling is kinda of a solved problem upstream in openswoole at least (I am using openswoole atm).
https://github.com/openswoole/openswoole/blob/master/example/src/Coroutine/MySQLClientPool.php
Also available: Redis, Postgres.
Going to implement a mysql and redis pool next, which seems to be the last step I need to get the whole thing running blazingly fast. It is actually quite amazing how fast everything is.
@SMFloris Nice! Iād suggest using Swoole rather than Openswoole for testing - all Swoole development happens there. The whole āsecurityā thing was blown completely out of proportion by the Openswoole guy who now just repackages Swoole by himself to try and steal some brand recognition.
Also one of the core Swoole maintainers (@deminy) has said heās happy to answer questions to help: https://github.com/swoole/swoole-src/pull/4330#issuecomment-1837271923
Re: the performance difference - yeah Iāve used Hyperf for several high load projects and the difference is night and day. It can handle approx 40x more req/s than Laravel Octane thanks to being built with coroutines from the ground up. Pretty comparable to Go. Companies are building game server backends with it, which is pretty nuts for a PHP framework.
IMHO properly implementing coroutines in Laravel would open up the framework to a whole group of devs who would never have considered PHP otherwise.
@huangdijia is a core Hyperf contributor and might be willing to review your PR too
Iād also suggest posting some benchmarks with your PR to show the performance benefits.
@binaryfire thanks for your input! Will use Swoole going forward.
I was just thinking that the level of speed is at the level of Go as well.
What I'll do after implementing the pooling connections as well (I'm trying not to hack to much, doing things the Laravel way as much as possible) is that I'll create a repo with a docker compose so that anyone can run the benchmark easily.
What sort of things would be nice to benchmark? I'm thinking of a route that simply returns an OK status and a route that does some inserts or reads from the database. I personally want to compare: simple Laravel behind nginx, laravel octane as it currently is and laravel octane with all the bells and whistles from coroutines.
This weekend I made some headway;
Turns out there are allot more stuff to wire together than I thought initially.
Why not using coroutine hooks?
It don't need to change code base, just hooking the PHP C code interface.
We can enable it by calling \OpenSwoole\Runtime::enableCoroutine();
before worker start.
I've tried it as issue #906 mentioned but encountered some issues in binding process.
We really look forward to Octane supporting Swoole coroutines, which will bring higher performance and solve more business scenarios. We hope the official will include this in the roadmap as soon as possible.