Comments 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.
Спасибо за дополнение. А Вы не можете также просвятить на тему того, чем отличается PHP FastCGI от FPM, который расшифровывается примерно в то же: FastCGI Process Manager? Вернее, даже, интересует, не чем они отличаются (на сайте php.net это описано), а зачем понадобилось это разбиение и почему нельзя было реализовать фишки FPM в рамках PHP FastCGI?
Основное отличие — кто отвечает за запуск 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.
Спасибо за комментарий. Но это фактически означает, что раз уж мы начали использовать php-fpm, то нет ни одной причины, которая может нас остановить от перехода на nginx. .htaccess — может быть аргументом, но его можно корректно конвертировать в директивы nginx.
Причины оставаться на Apache, к сожалению, есть, и вылезают практически на каждом из проводимых мной учебных курсов по Nginx. Навскидку (не только про PHP):
- Софт динамически переписывает .htaccess, и по какой-то причине нельзя «заморозить» результат.
- Используется авторизация через CAS или Shibboleth, что в Debian или Ubuntu для Apache означает установку mod_auth_cas или mod_shib2 из репозитория, или компиляцию соответствующего модуля Nginx из исходников, а компиляция запрещена начальством.
- Требуется «липкая» балансировка на несколько бекендов (в Apache есть из коробки), и нет ни денег на Nginx Plus, ни желания собирать nginx-sticky-module-ng из исходников.
AEP спасибо, что пояснили.
По пунктам — ничего удивительного, но что-то нужно менять в этом мире.
1. Это кривой софт. Лучше, если софт реализован в виде отдельного бекенд-приложения, которое инкапсулирует в себе эту историю с реврайтами. Ну, например, uwsgi + python + flask или django.
2. Пахнет самодурством начальства. Я бы понял, если там речь шла бы про ИБ и про сложность взаимодействия с ops. Но если рациональнее использовать перекомпилированный и собранный в пакет nginx, то стоит рассмотреть предложение об улучшении. Понимаю, что ситуации бывают разные, но я бы от работодателя-самодура бежал сломя голову, благо предложений (нормальных) хватает.
3. Я так понимаю, что на самом деле это вытекает из п.2. Пересобрать nginx это не страшно )
По пунктам — ничего удивительного, но что-то нужно менять в этом мире.
1. Это кривой софт. Лучше, если софт реализован в виде отдельного бекенд-приложения, которое инкапсулирует в себе эту историю с реврайтами. Ну, например, uwsgi + python + flask или django.
2. Пахнет самодурством начальства. Я бы понял, если там речь шла бы про ИБ и про сложность взаимодействия с ops. Но если рациональнее использовать перекомпилированный и собранный в пакет nginx, то стоит рассмотреть предложение об улучшении. Понимаю, что ситуации бывают разные, но я бы от работодателя-самодура бежал сломя голову, благо предложений (нормальных) хватает.
3. Я так понимаю, что на самом деле это вытекает из п.2. Пересобрать nginx это не страшно )
По пункту 2 объяснение от начальства той фирмы на самом деле получено. «Мы пытались что-то раньше собирать из исходников, а потом никого из команды не удавалось элементарно заставить следить за обновлениями безопасности и за совместимостью. А если ставить из пакета, то этим занимается за нас сопровождающий из Debian. И в данном конкретном случае, Apache работает и сам обновляется через unattended-upgrades, не трогай.»
На ЛОРе подсказали, HTTP/2-индикатор для Firefox в виде аддона.
У меня один вопрос: зачем Apache?
Ну хотя бы потому что про апач такой статьи ещё нет. И не смотря на то, что апач нынче не на коне, он всё ещё используется, на нём крутятся проекты, и HTTP/2 там не помешает. Так почему бы статье не быть?
Во всех тех случаях когда мне нужен по каким-либо причинам Апач — я ставлю перед ним Nginx, который обеспечит HTTP/2 и все остальные плюшки.
Напомните, nginx научился сквозную kerberos-авторизацию? Мне, например, это надо внутри конторы для внутреннего же RT. Безусловно, любой средне- и выше нагруженный общедоступный веб-сервис у меня тоже на nginx.
Я думаю, что все это можно прикрутить. Другой вопрос, что не зная Вашей конкретной задачи, ничего полезного посоветовать не смогу.
Есть модуль: github.com/stnoonan/spnego-http-auth-nginx-module
А вообще я, конечно же, имел в виду сервисы торчащие голой попой в интернет и имеющие какую-никакую нагрузку. Внутри энтерпрайзов, возможно, действительно проще поставить Апач сразу с нужными модулями и не заморачиваться со сборкой.
А вообще я, конечно же, имел в виду сервисы торчащие голой попой в интернет и имеющие какую-никакую нагрузку. Внутри энтерпрайзов, возможно, действительно проще поставить Апач сразу с нужными модулями и не заморачиваться со сборкой.
Вы считаете, что апач, торчащий наружу — это «голой попой»? Если да, то почему? Не придираюсь, мне действительно интересно.
До 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
Понятно. Спасибо.
Для справедливости: я когда работал в хостинг-компании, то у нас была проблема, что медленные клиенты (например, мобильники) забивали пул соединений nginx… Полагаю, что с правки ситуация попросту была бы хуже и проблемы наступили раньше
Конечно, любой пул можно забить:
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)
UFO just landed and posted this here
К сожалению, на шареде никто не даст крутить пхп-фпм и сильно менять конфигурацию апача (если это вообще возможно). Поэтому — да, htaccess там живёт, и нет — статья клиентам такого хостинга не поможет
На любом уважающем себя шареде сейчас будет стоять сpanel, а она вполне себе позволяет работать и с PHP-FPM и с http/2 — так что с этим проблем не должно быть. Что не меняет, конечно, того что статья клиентам такого, например, хостинга не поможет.
Судя по заголовку, цель просто странная: http/2 поднимается на веб-сервере, остальные компоненты уравнения (ОС, бекэнд, ЯП) точно не при чем.
Пишите либо правильные заголовки, либо правильные статьи. А поднять на nginx поддержку http/2 — это одно слово, если https настроен, правда же?
Статья о том, как это сделать на Apache. При чём тут nginx?
Да, спросонок не то написал. Ну так и в apache включить http/2 несложно, при чем тут php?
Sign up to leave a comment.
Настройка HTTP/2 на примере Apache 2.4, PHP 7 и Ubuntu 18.04 LTS