Pull to refresh

Comments 42

Проблема в том, что любая блокирующая операция (запрос в базу данных, file_get_contents итд.) заблокирует всех клиентов.

Потому писать код в таком ключе нужно совсем по другому…
И да, и не совсем.
В обычном PHP-FPM у нас же тоже всё блокируется. Как решаем проблему? Создаем пул воркеров и распределяем нагрузку по ним. Вот только в случае с ReactPHP не приходится поднимать всю систему заново, классы уже загружены, некоторые неизменные объекты тоже можно использовать для разных запросов, именно это и дает основной прирост производительности — PHP перестает умирать после каждого запроса.
что мешает запустить n серверов одновременно и балансировать нагрузку с nginx
Можно было бы использовать новую фишку uWSGI — phpsgi, вот только автор пока, похоже, отложил её в долгий ящик — не реализована как минимум обработка данных в POST-запросах.
Кстати, встроенные возможности uWSGI (планировщик, спулер, мулы и т.д.) могли бы решить часть проблем с блокирующими операциями.
обработка данных в POST запросах реализована, не реализована конкретно обработка multipart запросов, это несколько другая штука и в принципе ее можно добавить, готовые парсеры запросов существуют, единственнео что я под это дело все же отдельный бы воркер запилил.
UFO just landed and posted this here
Ну доя например рид-онли сайтов вполне может подойти думаю. Конечно в любой проект засунуть не получится
Рид-онли можно и статику нагенерить и раздавать тем же nginx…
Ну зависимо от количества. Я уже видел статический магазин на 8 гигабайт файлов как следствие множества продуктов и страниц. Для таких имхо статиуа уже проблемно
данные из $_POST нужно тащить какими-то костылями

не кастылями, а через абстракцию над SAPI (тот же PSR-7 предоставляет чудные интерфейсы для этого дела).

и всячески избегать синхронных операций и утечек памяти

Ну с утечками памяти да, хотя опять же можно просто иногда перезагружать воркеры. Что до «избегать сихронных операций» — я чуть ниже отписал.
Буквально вчера замерял то же на Yii 2.0 и пришёл к выводу о практической бесполезности использования этого дела в рамках фреймворка…
Поигрался еще и все действительно упирается в синхронний доступ к БД. Сейчас пробую php-pm
Можно и асинхронный попробовать, в mysqli есть такая возможность
Как уже отмечали люди выше, писать асинхронщину бывает больно, но если есть желание сделать что-то типа честного fastcgi и при этом не менять код то есть альтернативное решение на базе того же reactphp — php-pm. По сути это менеджер процессов который будет поднимать ваше приложение и ожидать запроса. После завершения обработки запроса можно либо перезагрузить воркер либо просто почистить его (например в случае с доктриной — отчистить UoW). Если вся наша система является stateless или легко сама себя чистит нам более не придется перезагружать воркеры и тратить серверное время на бутстрап приложения с инициализацией сервисов и т.д. Что до утилизации CPU — можно просто увеличить количество воркеров или сделать нормальный пайплайнинг — например отдельный коркер принимающий запросы и отдельные воркеры для их разбора.

В самом простом случае можно просто поднять RPS за счет устранения времени на бутстрап приложения (все же обычно не изветсно оставляют ли сервисы что-то после себя и ускорение за счет того что приложение будет висеть всегда уже нужно будет намного серьезнее тестить на всякие побочные эффекты).
Типа «пишем демона на PHP»? Ну ок, а зачем?
Производительность? Вы с чем конкретно сравнивали?
>в отличии от стандартного подхода с Apache и Nginx где процесс умирает по окончании обработки одного запроса
вроде как такие стандартные подходы остались в веселом прошлом?
Не остались ) фреймворки поднимаются с нуля при каждом запросе
А почему вы не любите чтото вроде apc? По сравнению с ним, я думаю не будет такого ускорения.
apc (к слову нынче opcache, который еще с 5.5 по умолчанию в ядре пыха) это лишь опкод кэшер, он не избавляет нас от необходимости на каждый запрос инициализировать систему, заного подключаться к базе и т.д. Он всего-лишь избавляет от необходимости работы с файловой системой так как уже распаршенные опкоды висят в общей памяти. Opcache еще в довесок расширяет оптимизации дополнительно, например кэш строк хранит не для процесса а для всего пула процессов, чем экономит память существенно… Даже в этом случае инициализация приложения это какое-то время, которое для некоторых критично (скажем если у вас 100 милисекунд на запрос это порог, вы явно захотите убрать лишние 10-15 милисекунд инициализации системы.
В заголовке написано — ускоряет в 8 раз. Вот интересно было по сравнению с чем, с голым апачем и php как cgi? Ну так толку так сравнивать. Apc или что-то другое это уже тонкости.
Автор проверял hello world, пустой контроллер, никакой бизнес логики и т.д. То есть по сути измерения проводились между «разбор запроса + маршрутизация + время инициализация приложения» и «разбор запроса + маршрутизация без учета времени инициализации приложения».

То что автор не описал методику испытаний это уже само по себе попахивает маркетингом… но по сути без разницы с чем сравнивать, цифры будут примерно одинаковыми. Как никак если пых у нас был без opcache в одном случае то во втором это просто не играет роли так как весь код и так в памяти крутится.

>но по сути без разницы с чем сравнивать
В том то и прикол, что если запустить олдскульно PHP как CGI на Апаче то разница возможно как раз и будет гдето в десять раз.
Ну вот я и удивился — оно так нафига делать)
оно так нафига делать

Давайте будем реалистами, скорее всего автор взял свой типовой стэк и на нем все гонял. Откуда взялась цифра «в 8 раз» я в принципе уже расписал — это ускорение за счет отсутствия времени инициализации фреймворка. Профит более чем очевидный, более того php-pm уже довольно часто используется для увеличения RPS на продакшене.
вроде как такие стандартные подходы остались в веселом прошлом?

Нет, после завершения запроса процесс просто перезапускается и в случае с php-fpm нет расходов по времени на запуск самого PHP. А вот приложение как запускалось с нуля так и запускается на каждый запрос (разве что с opcache это дело сильно ускоряется). Подходы с php-pm позволяют нивелировать и эти накладные расходы и при этом продолжать писать сихронный код не заботясь о том что у нас там демоны.
> (разве что с opcache это дело сильно ускоряется)
Я всякое подобное и имею ввиду, а есть еще apc, hhvm и тд и тп.
Вот лично я в чистом виде apache + php давно в серьезных проектах не видел.
в чистом виде apache + php давно в серьезных проектах не видел.

Ну потому и нет смысла об этом упоминать.

а есть еще apc, hhvm и тд и тп.

apc уже нет (только для php5.4 и менее), есть opcache + apcu разве что, hhvm это совсем другая штука, там ускорение опять же за счет того что у нас:
— код хранится в памяти и его не надо разбирать заного (мы этого можем добиться включив opcache и вырубив полностью инвалидацию кэша, хоть это имеет смысл делать только на больших нагрузках)
— JIT позволяет оптимизировать опкоды и генерить оптимизированный под текущую задачу машинный код. В PHP на данный момент для каждого опкода в каждый момент времени выполняется один и тот же машинный код (что логично), а HHVM в зависимости от контекста — разный, за счет этого мы получаем возможность оптимизаций. PHP7 подготовил неплохую почву для внедрения JIT в будущем, да и в рамках OpCache чуваки из Zend уже выложили их PoC реализацию (правда которая пока не особо работает и ждет своего часа).
>Ну потому и нет смысла об этом упоминать

Так я с чего и начал, с чем сравнивают то? А так то писать демона на PHP на нагрузках это не сильно здравая идея.
Это сильно зависит от задачи. Зачастую куда дешевле демонизировать существующий код, чем переписывать его на другом языке, тем более если надо будет поддерживать синхронно обе версии.
Как зачем? Чтобы увеличить производительность без смены используемого стакан технологий.
Давно не следил за PHP, в нем уже перестала течь память и его больше не нужно перезапускать каждые N обработанных запросов?
с версии 5.3 сборщик мусора начал поддерживать циклические ссылки, так что проблему могут составлять только кривые расширения. В целом же уже добрых лет 5 можно писать демоны на PHP.
А если кто-то напишет статью в духе «php теперь может не умирать» вы ему тоже поверите наслово? У меня в продакшене крутится уже почти пол года апишка на reactphp (по сути архитектура такая же как и в php-pm но с минимальными отличиями), знаю людей у которых php-pm крутится, и так же никаких проблем.

Проблемы с долгоиграющими PHP скриптами обычно вызваны:
— руки из одного места
— кривая обработка ошибок
— использование стремных экстеншенов для PHP (стандартные штуки которые нужны для всего этого добра, типа libev/libeveb, libuv, pcntl проблем не вызывали) которые текут.

В целом же проблем с php-pm нет вообще никаких, у нас в качестве демона только менеджер процессов и обработка запросов, а воркеры вы можете хоть после каждого запроса перезапускать.
UFO just landed and posted this here
UFO just landed and posted this here
ну не совсем неудавшийся, так как это вынудило создать phpng, какой-никакой а профит. То что валяется сейчас на гитхабах в теории должно ускорять всякие мелочи типа вызовов функций и т.д. просто до phpng накладные расходы на управление памятью были слишком большие (работа с кучей, большие кэш мисы и т.д), а после phpng уже просто не занимались JIT-ом, времени небыло. В перспектике JIT в совокупности с phpng даст еще больший профит, и кто знает, может кто-то возьмется пока чуваки из zend заняты.
UFO just landed and posted this here
какие дополнительные оптимизации?
Sign up to leave a comment.

Articles