Why can spool speed up PHP

Time:2021-7-22

preface

Recently in researchSwooleI’ve been listening to others all the timeSwooleIt can speed up. It’s always stupid. It’s been studiedSwooleAfter that, I had some understanding of myself.

The black history of php-cgi

aboutPHPWhen dealing with network requests, we basically reuse themCGIIt’s done in a different way. So, what is itCGIWell.

CGI

CGI, full nameCommon Gateway InterfaceIt is called “common gateway interface” in Chinese. Maybe a lot of people think thatCGIIt’s a program. Yes, I used to think so. Until I started to study it in detail from httpHTTPAfter the agreement, I found out thatCGIIt’s an agreement. Any programming language can be implementedCGISo any language can be used as the background language of the website.

PHP-CGI

It says,CGIIt’s an agreement, so,PHPI have my own rightCGIThat’s the realization ofPHP-CGI。 However, with the development of technology, people begin to realize that,PHP-CGIThe performance is not so satisfactory. We know,PHPAt run time, it depends on the configuration filephp.iniYes. So, wheneverPHP-CGIWhen it starts to work, it is a complete new process, it needs to reload the configuration file and initialize, which causes a great waste of resources and time.

FastCGI

So, how can we avoid this kind of waste? Smart programmers have come up with another way: why don’t we load the configuration in advance, and then, each executed task only needs to copy the current process, so that we can avoid the above waste. therefore, FastCGIThen he was born.

FastCGI, full nameFast Common Gateway Interface“Fast public network management interface”. Yes, it’s another agreement. Of course, this agreement is not becausePHPOnly then.

Apache (httpd)

Almost all of themWebAll containers are implementedFastCGIThe function of. First of allhttpd。 aboutPHPFor example,httpdIs to achieve a goal by itselfFastCGIOf the module. It will be preloadedphp.iniFile. Until there is a need to enterPHPWhen processing,PHPYou don’t have tophp.iniIt’s reloaded. That’s every changephp.iniAfter all have to restarthttpdService.

Nginx and PHP FPM

php-fpmYesFastCGIAn implementation of the. Usually we willNginxOfPHPProcessing part of the agent tophp-fpmOn the port of, give it tophp-fpmTo deal with it. andphp-fpmThe same way is to preload the configuration and then give it to the child process. It will manage the process.

Swoole

The hot question is,php-fpmAlthough it has been realizedFastCGIHowever, when it processes the request, it still needs to rerun a script, such asLaravelFor the same framework, loading so many dependencies and files at the beginning is still a big overhead. Let’s take a lookLaravelOfpublic/index.phpSource code of.

require __DIR__.'/../bootstrap/autoload.php';
$app = require_once __DIR__.'/../bootstrap/app.php';
$kernel = $app->make(Illuminate\Contracts\Http\Kernel::class);
$response = $kernel->handle(
    $request = Illuminate\Http\Request::capture()
);
$response->send();
$kernel->terminate($request, $response);

Take a look at the previous two statements. How many dependencies need to be loaded? It’s a lot of time and resources. Every request needs to be loaded. It’s really painful.

So, why can’t we, as before, not reload the configuration fileFastCGIHow about a way that you don’t have to load so many dependencies?

Of course, at this timeSwooleIt will come in handy. Since it’s through$app->makeTo generate a newKernelObject, thenApplicationObject of$appOf course, nothing will change. So, we can send the request before we receive it$appWell, it’s fast, isn’t it? We can make a simple transformation to it.

require __DIR__.'/../bootstrap/autoload.php';
$app = require_once __DIR__.'/../bootstrap/app.php';
$serv = new \Swoole\Server\Http('127.0.0.1', 9501);
$serv->on('request', function ($req, $res) use ($app) {
    $kernel = $app->make(Illuminate\Contracts\Http\Kernel::class);
    $response = $kernel->handle(
        $request = Illuminate\Http\Request::capture()
    );
    $res->end($response);
    $kernel->terminate($request, $response);
});
$serv->start();

Well, we can now listen to port 9501 by executing this script. And then it’s likeNginxto configurephp-fpmJust configure it the same way. In this way, we can see that before receiving the request, the dependency has been loaded, and the rest is to process the request.

Of course, my change is very simple and can’t be used in the production environment at all. I just provide an example.

Postscript

The above is just my own understanding and summary of my own understanding. aboutSwooleI’m still exploring, because it just needs too much, and it needs a little accumulation. There may be something wrong with this article. Welcome to make bricks!

Recommended Today

What should I do to become a full stack engineer?

Introduction: how to become a full stack engineer? What technical accumulation is required? What are the benefits of being a full stack engineer? I hope this article can provide some help for students who hope to become engineers of the whole stack and share with them. As developers, we don’t excessively distinguish between server and […]