Во время очередной сессии обновления систем, мне пришла в голову идея - почему бы не оставить в стороне php-fpm и не запустить свои приложения на php за каким-нибудь сервером приложений. Что у нас есть на выбор из более-менее производительных и в то же время эффективных по памяти вариантов? Вобщем-то немного. Сам php-fpm, uWSGI, nginx unit. вот собственно и весь список.
загуглив вопрос производительности, я узнал, что uwsgi с некоторого времени заметно прокачался и с версии 2.0.12 (2015-й год) более-менее неплохо себя ведёт. Nginx Unit - довольно специфичный сервер приложений и тоже ведёт себя неплохо. Во многих тестах uwsgi и unit оказывались постабильнее в работе, чем php-fpm. Ну, то есть если их задавить запросами, то они начинают деградировать по времени, но более-менее консистентно. В отличие от них разброс по времени ответа у php-fpm с нагрузкой растёт значительно и при относительно большой нагрузке fpm начинает таймаутить. Это какбэ не айс.
Убедил себя попробовать. Благо, что unit, что uwsgi вобщем-то несложно запустить и посмотреть как оно себя ведёт. На стороне nginx-а надо настроить http_pass в очередной сервер приложений.
Берём alpine linux и оказывается, что uwsgi там бракованный - есть поддержка только для питоновых приложений. Такого подвоха я не ожидал. Роскошный сервер приложений так изуродовать надо постараться. Запишем этот минус в карму мэйнтэйнеров alpine linux.
Остаётся nginx unit. Ну, что же - давайте возьмём его за рога и настроим поработать. вся настройка сводится к генерации json-а и скармливанию его в control socker сервера приложений. Далее он сам поднимает listener на нужных ip:port и настраивает пул приложений.
На самом деле, под капотом у него не человекочитаемый json в каталоге /var/lib/unit/conf.json. То есть можно писать в него и рестартовать unit.
Примерно такой конфиг достаточно затолкать в unit, чтобы он поднял на 8380 сервер приложений:
{
"applications": {
"my_app": {
"type": "php",
"processes": {
"max": 5,
"spare": 2
},
"user": "www",
"group": "www",
"root": "webroot_dir",
"index": "index.php"
}
},
"listeners": {
"127.0.0.1:8380": {
"application": "my_app"
}
}
}
Запихивается конфиг в запущенный сервер приложений вот так:
curl -X PUT --data-binary @config.json --unix-socket /run/control.unit.sock http://localhost/config
Есть важный момент. Рекомендуется прятать unit за frontend и не выставлять наружу неприкрытым.
На самом деле сам по себе сервер приложений рассчитан больше на администраторов, а не на разработчиков. То есть конфигурировать и обслуживать его довольно просто. Расширенных настроек в нём пока очень мало. Другое дело uwsgi...
После установки unit в качестве сервера приложений время отклика от web-приложений изменилось примерно также как после перехода с apache+mod_php на nginx+php-fpm. То есть джиттер в ответах сократился, что сказалось положительным образом на ajax-запросах, точнее на ответы на них (то есть с tt-rss, например, стало удобнее работать).
Однако, не все приложения согласились с таким переходом, например Grav посчитал, что я делаю какую-то ересь и отказался нормально запускаться.
Подводя итоги вышесказанному - уход от php-fpm в сторону unit или uwsgi вполне оправдан, также оправдан, как переход от apache+mod_php в сторону nginx+сервер приложений.