laravel / octane

Supercharge your Laravel application's performance.
https://laravel.com/docs/octane
MIT License
3.71k stars 284 forks source link

Looking forward to support for Swoole coroutines #765

Closed clemask closed 8 months ago

clemask commented 8 months ago

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.

taylorotwell commented 8 months ago

Feel free to work on it! šŸ‘

clemask commented 8 months ago

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.

driesvints commented 8 months ago

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.

binaryfire commented 7 months ago

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.

driesvints commented 7 months ago

Welcoming prs šŸ‘

huangdijia commented 7 months ago

If you want octane to support coroutine, you must first make database, redis, etc. support connection pooling.

binaryfire commented 7 months ago

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.

taylorotwell commented 7 months ago

@binaryfire I review all PRs - merging just depends on added complexity / maintenance burden. šŸ‘

fannyfan414 commented 7 months ago

It would be amazing feature for highload apps!

foremtehan commented 1 month ago

Can this be related? šŸ‘€

image

binaryfire commented 1 month ago

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.

huangdijia commented 1 month ago

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

SMFloris commented 1 month ago

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?

fannyfan414 commented 1 month ago

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!

SMFloris commented 1 month ago

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.

binaryfire commented 1 month ago

@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.

SMFloris commented 1 month ago

@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.

SMFloris commented 1 month ago

This weekend I made some headway;

Turns out there are allot more stuff to wire together than I thought initially.

evan361425 commented 1 month ago

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.