ReactPHP ускоряет PHPixie в 8 раз

от автора

image

ReactPHP это сокет сервер на PHP созданный для постоянной обработки запросов в отличии от стандартного подхода с Apache и Nginx где процесс умирает по окончании обработки одного запроса. Поскольку инициализация кода таким образом осуществляется только один раз то на отдельном запросе мы упускаем весь оверхед от загрузки классов, запуска фреймворка, считывания конфигурации итд.

Ограничением тут является то, что программист должен помнить что процесс и все поднятые сервисы будут использованы множество раз и по этому доступ к глобальному или статическому скоупу не желателен. Это делает сложным использование ReactPHP с большинством фреймворков не созданных для такого подхода.

К счастью PHPixie сама отказалась от глобального и статического скоупов, что позволяет легко запустить ее из-под ReactPHP.

Для начала добавим его поддержку в проект:

php ~/composer.phar require react/react 

Затем создаем файл react.php в корневой папке:

<?php  require_once('vendor/autoload.php');  $host = 'localhost'; $port = 1337;  $framework = new Project\Framework(); $framework->registerDebugHandlers(false, false);  $app = function ($request, $response) use ($framework, $host, $port) {     $http = $framework->builder()->components()->http();      // Строим реальную URI запроса     $uri = 'http://'.$host.':'.$port.$request->getPath();     $uri = $http->messages()->uri($uri);      // Приводим запрос к PSR-7     $serverRequest = $http->messages()->serverRequest(         $request->getHttpVersion(),         $request->getHeaders(),         '',         $request->getMethod(),         $uri,         array(),         $request->getQuery(),         array(),         array(),         array()     );      // Передаем запрос в фреймворк     $frameworkResponse = $framework         ->processHttpServerRequest($serverRequest);      // Вывод ответа     $response->writeHead(         $frameworkResponse->getStatusCode(),         $frameworkResponse->getHeaders()     );     $response->end(         $frameworkResponse->getBody()     ); };  $loop = React\EventLoop\Factory::create(); $socket = new React\Socket\Server($loop); $http = new React\Http\Server($socket);  $http->on('request', $app);  $socket->listen($port); $loop->run(); 

Запускаем:

php react.php 

Теперь перейдя по ссылке localhost:1337/ видим ту же PHPixie только запущенную как сервер. Простой бенчмарк на дефолтном контроллере показал увеличение производительности примерно в 8 раз, что не удивительно если взять во внимание то на сколько меньше кода выполняется при каждом запросе. Для тех кто захочет повторить мой эксперимент заметьте что я добился наилучшего результата с библиотекой event как бекенда для ReactPHP (он может работать и без нее, но только чуть медленнее получается).

Правда сам ReactPHP вносит несколько ограничений. Во-первых вам все равно понадобится веб-сервер для статических файлов. Но самое грустное то, что из коробки он не поддерживает данные из тела запроса ($_POST), хотя существуют способы добиться этого.

Наличие постоянного рантайма открывает интересные возможности, как например создание чата без надобности во внешней базе данных. Конечно пока-что это только эксперимент, но если идея приживется то PHPixie может получить отдельный компонент с более широкой поддержкой ReactPHP, включая например сессии и загрузку файлов.

ссылка на оригинал статьи http://habrahabr.ru/post/264725/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *