roadrunner-server / roadrunner

🤯 High-performance PHP application server, process manager written in Go and powered with plugins
https://docs.roadrunner.dev
MIT License
7.92k stars 411 forks source link

Perfomance degradation on Laravel 5.8 #138

Closed Sho0terInfo closed 5 years ago

Sho0terInfo commented 5 years ago

I think, RR not ready for production use with Laravel

i7-7700k 64 GB DDR4 Debian

ab -kc 4 -t 60

RR 1.3.7 (32 piped workers) / PHP 7.3.3 / LARAVEL 5.8 (NO MEMLEAKS, memory usage stable)

Requests per second: 149.45 [#/sec] (mean) Requests per second: 71.93 [#/sec] (mean) Requests per second: 55.46 [#/sec] (mean) Requests per second: 46.01 [#/sec] (mean) Requests per second: 41.42 [#/sec] (mean) Requests per second: 37.43 [#/sec] (mean) Requests per second: 33.59 [#/sec] (mean) Requests per second: 32.06 [#/sec] (mean) Requests per second: 29.99 [#/sec] (mean) Requests per second: 28.61 [#/sec] (mean)

PHP-FPM 7.3.3 / LARAVEL 5.8 Requests per second: 325.42 [#/sec] (mean) Requests per second: 327.17 [#/sec] (mean) Requests per second: 326.85 [#/sec] (mean) Requests per second: 322.50 [#/sec] (mean) Requests per second: 325.70 [#/sec] (mean) ...etc

<?php

use Spiral\Goridge\StreamRelay;
use Spiral\RoadRunner\Worker;
use Spiral\RoadRunner\PSR7Client;
use Nyholm\Psr7\Factory\Psr17Factory;
use Symfony\Bridge\PsrHttpMessage\Factory\PsrHttpFactory;
use Symfony\Bridge\PsrHttpMessage\Factory\HttpFoundationFactory;
use Illuminate\Contracts\Foundation\Application;
use Illuminate\Contracts\Http\Kernel;
use Kernel\Http\Request;

require_once(__DIR__ . '/../vendor/autoload.php');

class RoadRunner
{
    protected $psr7;
    protected $requester;
    protected $responder;
    protected $app;
    protected $kernel;

    public function __construct()
    {
        $this->psr7 = new PSR7Client(
            new Worker(
                new StreamRelay(STDIN, STDOUT)
            )
        );
        $this->requester = new HttpFoundationFactory;
        $this->responder = new PsrHttpFactory($psr17 = new Psr17Factory, $psr17, $psr17, $psr17);
        $this->app = require_once(__DIR__ . '/../bootstrap/app.php');
        $this->kernel = $this->app[Illuminate\Contracts\Http\Kernel::class];
    }

    public function handle(): void
    {
        while ($psr7Request = $this->psr7->acceptRequest()) {

            $_SERVER['REQUEST_TIME_FLOAT'] = $_SERVER['REQUEST_TIME_FLOAT'] ?? \microtime(true);

            try {

                $this->psr7->respond(
                    $psr7Response = $this->responder->createResponse(
                        $response = $this->kernel->handle(
                            $request = Request::createFromBase(
                                $this->requester->createRequest($psr7Request)
                            )
                        )
                    )
                );

                $this->kernel->terminate($request, $response);

            } catch (\Throwable $e) {

                $this->psr7->getWorker()->error((string) $e);
            }
        }
    }
}

(new RoadRunner)->handle();
wolfy-j commented 5 years ago

Can you provide a bit more information about underlying application?

wolfy-j commented 5 years ago

Also, have you tried integrations where you don’t need to covert from one request format to another?

Sho0terInfo commented 5 years ago

Also, have you tried integrations where you don’t need to covert from one request format to another?

I dont know how to use laravel with pure psr7 request.

Can you provide a bit more information about underlying application?

Its hello-world-like application without any orm modelso or somethink heavy. All time wokrer use less then 16 mb RAM. But first requests TTFB takes near 2ms and during the test its up to 200ms without load.

wolfy-j commented 5 years ago

That is odd. Can you try one of the following integrations: https://packagist.org/packages/avto-dev/roadrunner-laravel https://packagist.org/packages/cubekode/roadrunner-laravel https://packagist.org/packages/hunternnm/laravel-roadrunner https://packagist.org/packages/updg/roadrunner-laravel

There is definitely something withing "terminate".

Sho0terInfo commented 5 years ago

That is odd. Can you try one of the following integrations: https://packagist.org/packages/avto-dev/roadrunner-laravel https://packagist.org/packages/cubekode/roadrunner-laravel https://packagist.org/packages/hunternnm/laravel-roadrunner https://packagist.org/packages/updg/roadrunner-laravel

There is definitely something withing "terminate".

SO, final solution. Its no RR issue, but... Laravel has some introduction features, like needs to reload Session and Auth service providers for reload its state. I have some Service Providers (like determinate current request language) wich needs to reload. In this service provider I am definening some view composers. AND problem here. In each request service provider add view comporsers wich NOT REPLACE and with each next request Template Endinge do more callbacks for each composed view. Its cause linear perfomance degradation. Be careful with long-life services :)

Requests per second: 761.20 [#/sec] (mean) Time per request: 7.962 [ms] (mean) Time per request: 1.990 [ms] (mean, across all concurrent requests)