Litespeed's PHP LSAPI [1] shows how good performance can be with other setups. It'll be great if FrankenPHP gets to the same state.
1. https://www.litespeedtech.com/open-source/litespeed-sapi/php
Debugging application servers in production comes with its own set of difficulties, but I don't see how this one is worse than others. If anything, the ability to start new sockets without restarting the process is a plus.
I feel like problems with monitoring may be down to lack of proper logging or experience. It's not like FPM is going to leak more memory than your code would in other running contexts. It doesn't "go down" since it spawns a new process for every request. My cold read is that there's something wrong with the code you're running, not with FPM.
PHP-FPM had been more resilient than the other services I run. Rock solid.
Roadrunner executes php-cli and connects it to its web server through GRPC; FrankenPHP uses an ad-hoc SAPI, it is more like Apache's mod_php, the Go code uses the PHP interpreter as a library, it's all in the same process.
RoadRunner only has a worker mode, and can only work with compatible apps; FrankenPHP has a "standard" mode compatible with all existing applications, and a worker mode that requires some code changes (like RR).
RoadRunner runner uses PSR-7 HTTP messages; FrankenPHP uses plain old superglobals and streams (both in normal and in worker modes), they are reset after each handled request.
RoadRunner is battle-tested and production ready; FrankenPHP is experimental and not yet ready for production use.
FrankenPHP can also be used as a Go library to integrate PHP into any Go program or server (theoretically, it should be possible to integrate FrankenPHP into Traefik or the local Symfony web server, which are written in Go).
> Roadrunner executes php-cli and connects it to its web server through GRPC;
RR communicates with the PHP process via pipes (stdin/out/err) via our protocol (similar to the IP protocol, we also have a tcp/unix-socket options and shared memory is coming soon). The RR server itself then has various options to connect to the world:
- gRPC (w/o the need to install the `gRPC-php` extension), HTTP (with a lot of different middleware), HTTPS, fCGI. - Queues: kafka, rabbitmq, sqs, beanstalk, nats (with like priorities and so on) - KV/noSQL: memcached, redis, boltdb, memory. - Workflows: Temporal.
I might forget smt, but the main idea is to have a very extensible server. With very little knowledge about Go, you may extend it with your plugins and build your RR binary. Or even embed the RR server into your Go application (https://github.com/roadrunner-server/roadrunner/tree/master/...).
The traditional idea is to build a plug-in for the parent webserver. By essentially "making a fork" of Caddy, if you want to add other plugins to Caddy and then incorporate them into FrankenPHP, it's a lot more work. If instead you ship a PHP plugin to Caddy, you can manage Caddy instead and mix and match different functionality in one place.
But I guess it's heretical to suggest somebody use plugins in Go, if the whole idea is everything is a static binary.
It uses mainline Caddy: https://github.com/dunglas/frankenphp/blob/main/caddy/go.mod
* run plugins as separate processes and expect them to implement a specific RPC api
Compiling in plugins is more practical in Go then it might be in another language, due to the regularity of the go build system.
I'v checked and unfortunately the video recording is not available for now, I will post a link here as son as available.
Is that it?
Previously, there was https://github.com/deuill/go-php which was PHP5 and PHP7, but you needed to build PHP with ZTS. I had to forke it to focus on PHP5 and bring some improvements - my primary goal was to port some legacy PHP over iteratively via the Strangler pattern. If it can still be useful to some, the fork is here - https://github.com/borancar/go-php
Some benchmarks against mod_php, nginx+php-fpm and swoole would be nice.
OPcache improves PHP performance by storing precompiled script bytecode in shared memory
https://www.php.net/manual/en/intro.opcache.phpLooks neat!
nginx, php-fpm, some init system, and the convoluted configuration needed to get logs out via Docker's logging mechanism.
This pattern is common for background workers too, such as running gunicorn + celery in separate containers (Python tools) but the same image is used for both. You can change the CMD at runtime by overwriting it (for example the `command` property in Docker Compose and Kubernetes).
This avoids needing to hack around things at the Docker level to install an init system and it gives you a way to split things out at runtime so you individually scale and log them as needed.
It does mean a change in your app would restart nginx since the image would change for both but this isn't that big of a deal. If that was a deal breaker then you could create separate images for each one to still avoid an init system running in your container.
Caddy has a supervisor plugin, so can start php-fpm itself and the containers entrypoint can be Caddy, which achieves similar objectives here that Caddy becomes a PHP application server.
Longer answer: avoiding infrastructure setup - for those who has infrastructure it makes no sense, for those who knows how to run things in Docker and not need much beyond it - eliminates the need of getting familiar with Docker Compose.
Having php stay in memory should make performance benefits [and make sense for the project], but that's different story.
If it is Go, can I not just compile the binary and execute ?
Docker is definitely not necessary, but it is the easiest way to ship something that just works. Since you need a bunch of build dependencies to compile PHP, the installation steps are different for every distro to pull those in with whatever's your package manager.
Coupled with a packaging system, like debian gives you, this is all pretty straightforward.
I ran into this yesterday, and turns out I don't want to install docker just to build a program...
My current setup is a DigitalOcean Droplet with Nginx and php-fpm.
Do you have any success story with this application server ?
What happened to the times where some crazy person would simply slap together an interpreter and call it a language?
Somehow, language creation got more and more sophisticated these days.
PHP, Ruby, and Node all use things like cURL or the same PCRE regex lib, but I've seen uninformed or misguided arguments about "how Node is better than PHP at making HTTP requests because of axios", and not "I like Axios more than Guzzle3".