node.js — без сохранения состояния & amp; асинхронный веб-сервер с PHP (и Symfony)

TL; DR: я не уверен, что эта тема имеет свое место в StackOverflow, но в основном это просто тема дискуссий и размышлений о создании приложений PHP, как мы это делаем, например, с NodeJS (поток запросов без сохранения состояния, асинхронные вызовы и т. Д.)

Ситуация

Мы знаем, что NodeJS может использоваться как веб-сервер и веб-приложение.

Но для PHP, внутренний веб-сервер не рекомендуется для производства (так говорится в документации).

Но, поскольку полный стек Symfony основан на Kernel какие ручки Request объекты, это означает, что мы должен иметь возможность отправлять множество запросов одному и тому же ядру, только если мы сможем «загрузить» веб-сервер php (не приложение), создав ядро ​​перед прослушиванием HTTP-запросов. И наш маршрутизатор только создаст объект Request и заставит ядро ​​обработать его.

Но для этого приложение Symfony должно быть без гражданства, например, нам нужна Doctrine, чтобы эффективно очищать единицу работы после запроса, или, может быть, нам понадобится изолировать некоторые компоненты, основанные на запросе (идентифицируя запрос с его уникальным идентификатором ссылки на класс PHP? Или используя другие процессы php?), и, очевидно, нам потребуется больше асинхронных вещей в PHP или в способе использования внутреннего веб-сервера. ,

Основные вопросы я иногда задаю себе, а теперь задаю сообществу

Чтобы уточнить это, у меня есть несколько вопросов о PHP:

  1. Зачем именно так внутренний веб-сервер PHP не рекомендуется для производства?
    Я имею в виду, что если мы сможем настроить работу сервера и его файл «маршрутизатора», мы сможем использовать его как любой сервер PHP, да или нет?
  2. Как это ведет себя внутренне? Распределяется ли память между двумя запросами?
    Используя маршрутизатор, мне кажется очевидным, что переменные не являются общими, иначе мы могли бы создавать приложения, похожие на nodejs, но кажется, что PHP не способен делать что-то подобное.
  3. Действительно ли возможно создать приложение с полным состоянием с помощью Symfony?
    например Я отправляю два разных запроса одному и тому же объекту ядра. В этом случае существует ли вероятность того, что эти два запроса вызовут конфликт в основных компонентах Symfony?
  4. На самом деле, идея «Создать ядро ​​-> запустить сервер -> по запросу, заставить ядро ​​обработать его» поведение было бы удивительным, потому что это было бы что-то очень похожее на NodeJS, но на самом деле парадигма PHP не совместима с этим, потому что нам нужно каждый запрос обрабатываться асинхронно. Но если ядро ​​и его контейнер не сохраняют состояния, тогда должно быть способ сделать что-то подобное, не так ли?

Некоторые мысли

Я слышал о Реагировать на PHP, Храповик PHP для интеграции Websocket, Сосулька, PHP-PM но никогда не испытывал их, мне это пока кажется слишком сложным (мне может не хватать некоторых понятий об асинхронности в приложениях, поэтому мой мозг не поймет, пока у меня не будет больше ответов: D).

Есть ли способ, чтобы эти библиотеки могли быть использованы в качестве «оболочек» для обработки запросов нашего ядра?

Я имею в виду, давайте создадим эту настройку реагирующей среды / icicle / независимо от среды, создадим наше ядро, как мы бы это делали в любом приложении Symfony, и запустим приложение как веб-сервер, и когда запрос будет получен, мы отправим его асинхронно в наше ядро, и пока ядро ​​не отправило ответ, клиент ожидает его, даже если ответ также отправлено асинхронно (из вложенных обратных вызовов и т. д., как в NodeJS).

Это сделало бы любое существующее приложение Symfony совместимым с этой парадигмой, если, конечно, приложение не имеет состояния. (если конфигурация приложения изменяется в зависимости от запроса, существует проблема парадигмы в самом приложении …)

Возможно ли даже использование PHP-библиотек, а не использование внутреннего веб-сервера PHP по-другому?

Зачем задавать эти вопросы?

На самом деле, это было бы своего рода революция, если бы PHP мог реализовать реальный внутренняя асинхронность, как в Javascript, но это также окажет большое влияние на производительность в PHP, поскольку постоянные данные на нашем веб-сервере будут меньше загружаться (требуется автозагрузчик, создание экземпляра ядра, получение тяжелых вещей из кэшированных файлов, разрешение маршрутизации, так далее.).

В моих мыслях только $kernel->handleRaw($request); будет потреблять процессор, все остальное (контейнер, параметры, сервисы и т. д.) будет уже в памяти, или, в случае сервисов, «ожидает создания экземпляра». Затем повышение производительности, я думаю.

И это может немного затронуть людей, которые все еще думают, что PHP — очень плохой и медленный язык для использования: D

Для читателей и респондентов;)

Если основной автор PHP читает меня, есть ли способ, чтобы внутренне PHP мог быть более асинхронным даже с определенным новым внутренним API, основанным на функциях или классах?

Я не профессионал во всех этих концепциях, и я надеюсь, что действительно хорошие эксперты прочитают это и ответят мне!

Это могло бы стать большим достижением в мире PHP, если бы все это было возможно в любом случае.

0

Решение

Почему именно внутренний веб-сервер PHP не рекомендуется для
производство? Я имею в виду, если мы можем настроить, как работает сервер и его
файл «router», мы должны быть в состоянии использовать его как любой сервер PHP, да или
нет?

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

По сути, в нем отсутствуют функции, если сравнить его с nginx, Это было бы равносильно сравнению скейтборда с Lamborghini.

Это может получить вас от A в B но .. ты понял суть.

Как это ведет себя внутренне? Распределяется ли память между двумя запросами?
Используя роутер, мне кажется очевидным, что переменные не являются
поделился, иначе мы могли бы создавать приложения, похожие на nodejs, но кажется, что PHP не
способен сделать что-то подобное.

Документация утверждает, что она однопоточная, поэтому кажется, что она будет вести себя так же, как если бы вы написали while(true) { // all your processing here },

Это игра, разработанная для быстрой проверки нескольких вещей, если вы не можете настроить надлежащий веб-сервер перед тем, как опробовать свой код.

Действительно ли возможно сделать приложение без состояния с
Symfony? например Я посылаю два разных запроса к одному и тому же объекту ядра,
в этом случае есть ли вероятность того, что два запроса создают
конфликт в основных компонентах Symfony?

Зачем ему идти к тому же объекту ядра? Почему бы не разработать свое приложение таким образом, чтобы оно не имело значения который объект или даже сервер обработки получает запрос? Почему бы не проектировать избыточность и высокую доступность с самого начала? HTTP = без сохранения состояния по умолчанию. Ваша задача = сделать неважным, что обрабатывает запрос. Это не сложно сделать, если вы избегаете связи с реальным сервером обработки (пример: не храните сессии в локальной файловой системе и т. Д.)

Собственно, идея «Создать ядро ​​-> запустить сервер -> по запросу»
заставить ядро ​​обрабатывать это «поведение было бы удивительным, потому что это
быть чем-то очень похожим на NodeJS, но на самом деле парадигма PHP
несовместимо с этим, потому что нам нужно, чтобы каждый запрос был
обрабатывается асинхронно. Но если ядро ​​и его контейнер
без гражданства, тогда должен быть способ сделать что-то подобное,
не так ли?

На самом деле, nginx + php-fpm вести себя почти идентично node.js,

nginx использует реактор для обработки всех соединений в одном потоке. Node.js делает то же самое. Что вы делаете, это создаете замыкание / обратный вызов, который подается в библиотеки Node, а ввод / вывод обрабатывается в многопоточной среде. Многопоточность абстрагируется от вас (относится к вводу / выводу, а не к процессору). Вот почему вы можете испытать это Node.js блокирует, когда его просят выполнить задачу, интенсивно использующую процессор.

nginx реализует точно такую ​​же концепцию, за исключением того, что этот обратный вызов не является замыканием, написанным на javascript. Это обратный вызов, который ожидает ответа от php-fpm в течение <timeout> секунд. Nginx позаботится об асинхронности для вас. Ваша задача — написать то, что вы хотите на PHP. Теперь, если вы читаете огромный файл, то асинхронный код в вашем PHP будет иметь смысл, за исключением того, что он на самом деле не нужен.

С nginx и отправка запросов на обработку в fastcgi рабочий, масштабирование становится тривиальным. Например, предположим, что 1 PHP-машины недостаточно для обработки количества запросов, с которыми вы работаете. Нет проблем, добавьте больше машин в пул nginx.

Это взято из документации nginx:

upstream backend {
server backend1.example.com       weight=5;
server backend2.example.com:8080;
server unix:/tmp/backend3;

server backup1.example.com:8080   backup;
server backup2.example.com:8080   backup;
}

server {
location / {
proxy_pass http://backend;
}
}

Вы определяете пул серверов, а затем назначаете различные параметры веса / прокси, связанные с балансировкой обработки запросов.

Тем не менее, важной частью является то, что вы можете добавить больше серверов, чтобы справиться с требованиями доступности.

Это причина, почему nginx + php-fpm стек привлекательный. поскольку nginx действует как прокси, он может запрашивать прокси node.js а также, позволяя вам обрабатывать связанные с веб-сокетом операции в node.js (который, в свою очередь, может выполнять HTTP-запрос к конечной точке PHP, что позволяет вам содержать всю логику вашего приложения на PHP).

Я знаю, что этот ответ может быть не тем, что вы ищете, но то, что я хотел выделить, это способ node.js работает (концептуально) идентично тому, что nginx делает, когда дело доходит до обработки входящего запроса. Вы могли бы сделать php работает как узел, но в этом нет необходимости.

4

Другие решения

Ваши вопросы можно обобщить так:

«Может ли PHP быть больше похож на Node?»

на что ответ, конечно, «да». Но это приводит нас к другому вопросу:

«Должен ли PHP быть больше похож на Node?»

и теперь ответ не так очевиден.

Конечно, теоретически PHP можно сделать более похожим на Node — даже до такой степени, чтобы сделать его точно таким же. Просто возьмите следующую версию Node и назовите ее PHP 6.0 или что-то в этом роде.

Я бы сказал, что это будет вредно как для Node, так и для PHP. По разным причинам в средах выполнения есть разнообразие. Одним из вариантов является модель параллелизма, используемая в данной среде. Создание одного как другого означало бы меньше выбора для программиста. И меньше выбора — меньше свободы выражения.

PHP и Node были созданы в разное время и по разным причинам.

PHP был разработан в 1995 году и назывался Personal Home Page. Вариант использования заключался в добавлении некоторых динамических функций на стороне сервера в HTML. У нас уже были SSI и CGI на тот момент, но люди хотели иметь возможность вставлять прямо в HTML — синхронно, иначе это не имело бы большого смысла — результаты запросов к базе данных и других вычислений. Не удивительно, насколько она хороша на этой работе даже сегодня.

Node, с другой стороны, был разработан в 2009 году — почти 15 лет спустя — для создания высокопроизводительных сетевых серверов. Поэтому нас не должно удивлять, что писать такие серверы в Node легко и они имеют отличные характеристики производительности. Вот почему Node был создан в первую очередь. Одним из решений, которое он должен был сделать, была 100% неблокирующая среда однопоточных, асинхронных циклов событий.

Теперь однопоточность параллелизма концептуально сложнее, чем многопоточность. Но если вам нужна производительность для операций ввода-вывода, то у вас нет других вариантов. Вы не сможете создать 10000 потоков, но вы можете легко обрабатывать 10000 соединений с Node в одном потоке. Существует причина, по которой nginx является однопоточным и почему Redis является однопоточным. И одна из общих характеристик nginx и Redis — это потрясающая производительность, но оба из них было сложно написать.

Теперь, что касается Node и PHP, эти технологии настолько далеки друг от друга, что трудно даже понять, как будет выглядеть их слияние. Это напоминает мне старая первоапрельская шутка об объединении Perl и Python что так много людей верили в

У PHP есть свои сильные стороны, а у Node — сильные. И точно так же, как было бы сложно представить Node с блокирующим вводом-выводом, так же трудно представить PHP с неблокирующим вводом / выводом.

Подводя итог: возможно сделать PHP похожим на Node, но я не ожидаю, что это произойдет в ближайшее время — если вообще когда-нибудь.

2

По вопросам рекламы [email protected]