Комментарии 26
В статье отсутствует одно важное «почему» (а именно, почему нужно переходить на php-fpm), поэтому дополняю.
Обычный способ развертывания PHP вместе с Apache — это mod_php. Однако, PHP использует слишком много непотокобезопасных библиотек, и поэтому mod_php совместим только с MPM'ами, которые не используют потоки. Т.е. по факту только с mpm_prefork. Однако, как указано в статье, mpm_prefork несовместим с HTTP/2. Поэтому от корня зла (mod_php) надо избавиться, и заменить на отдельный процесс php-fpm, который работает независимо от Apache.
Обычный способ развертывания PHP вместе с Apache — это mod_php. Однако, PHP использует слишком много непотокобезопасных библиотек, и поэтому mod_php совместим только с MPM'ами, которые не используют потоки. Т.е. по факту только с mpm_prefork. Однако, как указано в статье, mpm_prefork несовместим с HTTP/2. Поэтому от корня зла (mod_php) надо избавиться, и заменить на отдельный процесс php-fpm, который работает независимо от Apache.
+5
Спасибо за дополнение. А Вы не можете также просвятить на тему того, чем отличается PHP FastCGI от FPM, который расшифровывается примерно в то же: FastCGI Process Manager? Вернее, даже, интересует, не чем они отличаются (на сайте php.net это описано), а зачем понадобилось это разбиение и почему нельзя было реализовать фишки FPM в рамках PHP FastCGI?
+1
Основное отличие — кто отвечает за запуск FastCGI-процесса. Спецификация FastCGI допускает как запуск веб-сервером, так и внешний запуск.
Раньше, до появления PHP-FPM и Apache 2.4, за запуск процесса отвечал Apache (а точнее, модуль mod_fastcgi или его более современный аналог — mod_fcgid). Запускал, давал сокет на stdin, и посылал туда запросы. Т.е. делал все, как предусмотрено спецификацией FastCGI, а именно разделом "Initial Process State". Другие веб-серверы так не умели, они хотели, чтобы процесс FastCGI запускал кто-то еще, а им оставалось только соединяться с сокетом и посылать туда запросы. Начиная с версии 2.4, к армии таких серверов присоединился и Apache с модулем mod_proxy_fasctgi.
Соответственно, получилась несостыковка интерфейсов: PHP из коробки (а именно, в виде /usr/bin/php-cgi или /usr/lib/cgi-bin/php) не умел запускаться так, как ожидает Nginx или mod_proxy_fasctgi. Разработчики Lighttpd в свое время решили проблему путем написания утилиты spawn-fcgi. Эта утилита запускается как обычный демон, создает слушающий сокет, запускает традиционный FastCGI-процесс и передает этот сокет ему на stdin.
«Почему нельзя было реализовать фишки FPM в рамках PHP FastCGI» — опять-таки, не поделили ответственность. Фишки FPM имеют смысл только в рамках концепции внешней запускалки для FastCGI-процессов. Т.е. в рамках PHP-FPM или mod_fcgid (который все равно бы не воспользовался дополнительными процессами, запущенными самим PHP, см. раздел «Special PHP considerations» тут), но не в рамках самого PHP. Исключение: использование через spawn-fcgi, как это делали пользователи lighttpd.
Раньше, до появления PHP-FPM и Apache 2.4, за запуск процесса отвечал Apache (а точнее, модуль mod_fastcgi или его более современный аналог — mod_fcgid). Запускал, давал сокет на stdin, и посылал туда запросы. Т.е. делал все, как предусмотрено спецификацией FastCGI, а именно разделом "Initial Process State". Другие веб-серверы так не умели, они хотели, чтобы процесс FastCGI запускал кто-то еще, а им оставалось только соединяться с сокетом и посылать туда запросы. Начиная с версии 2.4, к армии таких серверов присоединился и Apache с модулем mod_proxy_fasctgi.
Соответственно, получилась несостыковка интерфейсов: PHP из коробки (а именно, в виде /usr/bin/php-cgi или /usr/lib/cgi-bin/php) не умел запускаться так, как ожидает Nginx или mod_proxy_fasctgi. Разработчики Lighttpd в свое время решили проблему путем написания утилиты spawn-fcgi. Эта утилита запускается как обычный демон, создает слушающий сокет, запускает традиционный FastCGI-процесс и передает этот сокет ему на stdin.
«Почему нельзя было реализовать фишки FPM в рамках PHP FastCGI» — опять-таки, не поделили ответственность. Фишки FPM имеют смысл только в рамках концепции внешней запускалки для FastCGI-процессов. Т.е. в рамках PHP-FPM или mod_fcgid (который все равно бы не воспользовался дополнительными процессами, запущенными самим PHP, см. раздел «Special PHP considerations» тут), но не в рамках самого PHP. Исключение: использование через spawn-fcgi, как это делали пользователи lighttpd.
+4
Спасибо за комментарий. Но это фактически означает, что раз уж мы начали использовать php-fpm, то нет ни одной причины, которая может нас остановить от перехода на nginx. .htaccess — может быть аргументом, но его можно корректно конвертировать в директивы nginx.
+2
Причины оставаться на Apache, к сожалению, есть, и вылезают практически на каждом из проводимых мной учебных курсов по Nginx. Навскидку (не только про PHP):
- Софт динамически переписывает .htaccess, и по какой-то причине нельзя «заморозить» результат.
- Используется авторизация через CAS или Shibboleth, что в Debian или Ubuntu для Apache означает установку mod_auth_cas или mod_shib2 из репозитория, или компиляцию соответствующего модуля Nginx из исходников, а компиляция запрещена начальством.
- Требуется «липкая» балансировка на несколько бекендов (в Apache есть из коробки), и нет ни денег на Nginx Plus, ни желания собирать nginx-sticky-module-ng из исходников.
+2
AEP спасибо, что пояснили.
По пунктам — ничего удивительного, но что-то нужно менять в этом мире.
1. Это кривой софт. Лучше, если софт реализован в виде отдельного бекенд-приложения, которое инкапсулирует в себе эту историю с реврайтами. Ну, например, uwsgi + python + flask или django.
2. Пахнет самодурством начальства. Я бы понял, если там речь шла бы про ИБ и про сложность взаимодействия с ops. Но если рациональнее использовать перекомпилированный и собранный в пакет nginx, то стоит рассмотреть предложение об улучшении. Понимаю, что ситуации бывают разные, но я бы от работодателя-самодура бежал сломя голову, благо предложений (нормальных) хватает.
3. Я так понимаю, что на самом деле это вытекает из п.2. Пересобрать nginx это не страшно )
По пунктам — ничего удивительного, но что-то нужно менять в этом мире.
1. Это кривой софт. Лучше, если софт реализован в виде отдельного бекенд-приложения, которое инкапсулирует в себе эту историю с реврайтами. Ну, например, uwsgi + python + flask или django.
2. Пахнет самодурством начальства. Я бы понял, если там речь шла бы про ИБ и про сложность взаимодействия с ops. Но если рациональнее использовать перекомпилированный и собранный в пакет nginx, то стоит рассмотреть предложение об улучшении. Понимаю, что ситуации бывают разные, но я бы от работодателя-самодура бежал сломя голову, благо предложений (нормальных) хватает.
3. Я так понимаю, что на самом деле это вытекает из п.2. Пересобрать nginx это не страшно )
0
По пункту 2 объяснение от начальства той фирмы на самом деле получено. «Мы пытались что-то раньше собирать из исходников, а потом никого из команды не удавалось элементарно заставить следить за обновлениями безопасности и за совместимостью. А если ставить из пакета, то этим занимается за нас сопровождающий из Debian. И в данном конкретном случае, Apache работает и сам обновляется через unattended-upgrades, не трогай.»
+1
На ЛОРе подсказали, HTTP/2-индикатор для Firefox в виде аддона.
+1
У меня один вопрос: зачем Apache?
+1
Ну хотя бы потому что про апач такой статьи ещё нет. И не смотря на то, что апач нынче не на коне, он всё ещё используется, на нём крутятся проекты, и HTTP/2 там не помешает. Так почему бы статье не быть?
+1
Во всех тех случаях когда мне нужен по каким-либо причинам Апач — я ставлю перед ним Nginx, который обеспечит HTTP/2 и все остальные плюшки.
+1
Напомните, nginx научился сквозную kerberos-авторизацию? Мне, например, это надо внутри конторы для внутреннего же RT. Безусловно, любой средне- и выше нагруженный общедоступный веб-сервис у меня тоже на nginx.
+1
Я думаю, что все это можно прикрутить. Другой вопрос, что не зная Вашей конкретной задачи, ничего полезного посоветовать не смогу.
0
Есть модуль: github.com/stnoonan/spnego-http-auth-nginx-module
А вообще я, конечно же, имел в виду сервисы торчащие голой попой в интернет и имеющие какую-никакую нагрузку. Внутри энтерпрайзов, возможно, действительно проще поставить Апач сразу с нужными модулями и не заморачиваться со сборкой.
А вообще я, конечно же, имел в виду сервисы торчащие голой попой в интернет и имеющие какую-никакую нагрузку. Внутри энтерпрайзов, возможно, действительно проще поставить Апач сразу с нужными модулями и не заморачиваться со сборкой.
+1
Вы считаете, что апач, торчащий наружу — это «голой попой»? Если да, то почему? Не придираюсь, мне действительно интересно.
0
До 2.4 версии Апач был не юзабелен просто по той причине что его можно было уложить открыв ну там, допустим, 300-500-1000 коннектов (смотря какой лимит стоит и сколько памяти) и забив весь PreFork пул. Это сейчас может случиться даже не со злого умысла кулхацкера, а просто потому что браузеры любят KeepAlive коннекты — открывают их много и не закрывают. Аналогично и с MPM Worker.
Сейчас туда прикрутили epoll/kqueue поверх Worker и назвали это MPM Event, который пытается делать то же самое что и Nginx — держать сотни тысяч коннектов открытыми. На деле это просто костыль, работающий медленнее в 2-3 раза.
Бенчмарки можно глянуть, например, тут: www.eschrade.com/page/performance-of-apache-2-4-with-the-event-mpm-compared-to-nginx
Сейчас туда прикрутили epoll/kqueue поверх Worker и назвали это MPM Event, который пытается делать то же самое что и Nginx — держать сотни тысяч коннектов открытыми. На деле это просто костыль, работающий медленнее в 2-3 раза.
Бенчмарки можно глянуть, например, тут: www.eschrade.com/page/performance-of-apache-2-4-with-the-event-mpm-compared-to-nginx
+1
Понятно. Спасибо.
0
Для справедливости: я когда работал в хостинг-компании, то у нас была проблема, что медленные клиенты (например, мобильники) забивали пул соединений nginx… Полагаю, что с правки ситуация попросту была бы хуже и проблемы наступили раньше
0
Конечно, любой пул можно забить:
1) Файловые дескрипторы
2) Память под открытые сокеты
3) Собственно упереться в потолок выставленного worker_connections (но это скорее вопрос конфигурации)
Вот только в случае стандартных Prefork/Thread моделей обработки запросов число открытых коннектов на некоем сферическом сервере не сможет превысить единицы тысяч (чаще — гораздо меньше). Ибо даже шедулить 1к тредов\процессов ядру *очень* тяжело — будет большой оверхед.
В epoll-like моделях без проблем можно иметь 1 миллион и более коннектов на сервер. Для примера можно взять github.com/valyala/fasthttp:
(модель работы Golang очень похожа на epoll)
1) Файловые дескрипторы
2) Память под открытые сокеты
3) Собственно упереться в потолок выставленного worker_connections (но это скорее вопрос конфигурации)
Вот только в случае стандартных Prefork/Thread моделей обработки запросов число открытых коннектов на некоем сферическом сервере не сможет превысить единицы тысяч (чаще — гораздо меньше). Ибо даже шедулить 1к тредов\процессов ядру *очень* тяжело — будет большой оверхед.
В epoll-like моделях без проблем можно иметь 1 миллион и более коннектов на сервер. Для примера можно взять github.com/valyala/fasthttp:
Currently fasthttp is successfully used by VertaMedia in a production serving up to 200K rps from more than 1.5M concurrent keep-alive connections per physical server.
(модель работы Golang очень похожа на epoll)
0
НЛО прилетело и опубликовало эту надпись здесь
К сожалению, на шареде никто не даст крутить пхп-фпм и сильно менять конфигурацию апача (если это вообще возможно). Поэтому — да, htaccess там живёт, и нет — статья клиентам такого хостинга не поможет
0
На любом уважающем себя шареде сейчас будет стоять сpanel, а она вполне себе позволяет работать и с PHP-FPM и с http/2 — так что с этим проблем не должно быть. Что не меняет, конечно, того что статья клиентам такого, например, хостинга не поможет.
0
Судя по заголовку, цель просто странная: http/2 поднимается на веб-сервере, остальные компоненты уравнения (ОС, бекэнд, ЯП) точно не при чем.
Пишите либо правильные заголовки, либо правильные статьи. А поднять на nginx поддержку http/2 — это одно слово, если https настроен, правда же?
0
Статья о том, как это сделать на Apache. При чём тут nginx?
+1
Да, спросонок не то написал. Ну так и в apache включить http/2 несложно, при чем тут php?
0
Зарегистрируйтесь на Хабре, чтобы оставить комментарий
Настройка HTTP/2 на примере Apache 2.4, PHP 7 и Ubuntu 18.04 LTS