Что такое php fpm
PHP → Коротко о CGI, FastCGI, PHP-FPM и mod_php
Решил навести в голове порядок о том, как работают вместе веб-сервер и PHP.
Common Gateway Interface, «общий интерфейс шлюза» — это стандарт, который описывает, как веб-сервер должен запускать прикладные программы (скрипты), как должен передавать им параметры HTTP-запроса, как программы должны передавать результаты своей работы веб-серверу. Прикладную программу взаимодействующую с веб-сервером по протоколу CGI принято называть шлюзом, хотя более распространено название CGI-скрипт или CGI-программа.
В качестве CGI-программ могут использоваться программы/скрипты написанные на любых языках программирования, как на компилируемых, так и на скриптовых, в том числе на shell.
CGI-скрипты были популярны до того, как для веб-разработки стали преимущественно использовать PHP. Хотя сам PHP интерпретатор позволяет работать в режиме CGI (см. ниже).
Основной момент: «CGI» это не язык программирования и не отдельная программа! Это просто протокол (стандарт, спецификация, соглашение, набор правил).
FastCGI
Дальнейшее развитие технологии CGI, является более производительным и безопасным, снимает множество ограничений CGI-программ.
FastCGI программа работает следующим образом: программа единожды загружается в память в качестве демона (независимо от HTTP-сервера), а затем входит в цикл обработки запросов от HTTP-сервера. Один и тот же процесс обрабатывает несколько различных запросов один за другим, что отличается от работы в CGI-режиме, когда на каждый запрос создается отдельный процесс, «умирающий» после окончания обработки.
Написание FastCGI программ-демонов сложнее чем CGI, нужны дополнительные библиотеки, зависящие от языка.
Опять же, сама аббревиатура FastCGI это не язык программирования и не отдельная программа, это как и в случае CGI — просто спецификация.
PHP в режиме CGI
PHP в режиме CGI это самый старый способ выполнения php-скриптов веб-сервером. Режим доступен по умолчанию, однако может быть отключён при компиляции.
Для Apache нужен модуль mod_cgi (поставляется вместе с Apache). Nginx из коробки поддержки не имеет, хотя существуют дополнительные инструменты.
В данный момент режим используется редко в силу малой производительности.
PHP в режиме FastCGI
Помимо CGI режима, PHP из коробки умеет работать и в FastCGI режиме (с версии 5.3 даже в двух FastCGI режимах). Режим включается флагом при компиляции интерпретатора, флаг зависит от версии PHP.
Для работы с Apache нужен модуль mod_fcgid или mod_fastcgi, либо связка из mod_proxy_fcgi + PHP-FPM.
Nginx умеет работать с FastCGI приложениями из коробки, но именно для PHP дополнительно нужен PHP-FPM (см. ниже).
Следует помнить, что при работе PHP в режиме FastCGI в памяти висит сам php интерпретатор, а не какой-то конкретный php-скрипт.
PHP-FPM
FastCGI Process Manager, «Менеджер процессов FastCGI». Это альтернативная реализация FastCGI режима в PHP с несколькими дополнительными возможностями, которые обычно используются для высоконагруженных сайтов.
Изначально PHP-FPM представлял из себя набор патчей от Андрея Нигматулина, которые устраняли ряд проблем, мешающих полноценно использовать PHP в режиме FastCGI (список улучшений). С версии PHP 5.3 набор патчей включён в ядро, а дополнительные возможности PHP-FPM включаются флагом при компиляции.
PHP-FPM используется в основном в связке с Nginx, без установки Apache.
mod_php
Это модуль для Apache, позволяющий ему выполнять php скрипты. Является наверно самым популярным и простым способом подружить Apache и PHP. Модуль не использует ни CGI, ни FastCGI. Есть свои минусы — скрипты работают под пользователем веб-сервера, невозможно использовать больше одной версии PHP.
Настройка PHP-FPM
Интерпретатор языка программирования PHP может работать в нескольких режимах. Он может быть интегрирован в веб-сервер в виде специального модуля или использоваться как отдельный сервис php-fpm. Аббревиатура FPM расшифровывается как Fastcgi Process Manager. Это сервис, который запускает несколько процессов, которые могут выполнять PHP скрипты. Процессы могут получить скрипты, которые надо выполнить по TCP или Unix сокетам.
Обычно php-fpm используется вместе с веб-сервером Nginx. В этой статье мы рассмотрим как выполняется настройка PHP-FPM для максимально эффективной работы на вашем сервере.
Настройка PHP-FPM
Менеджер процессов PHP-FPM может запускать несколько процессов обработчиков. Обычно для каждого отдельного сайта принято использовать отдельный обработчик, это позволяет распределить нагрузку и отслеживать статистику по каждому сайту. Поэтому есть общий конфигурационный файл php-fpm и конфигурационный файл для каждого обработчика, который обычно называется конфигурационным файлом пула. Обработчик принято называть пулом потому что на самом деле обработкой занимается не один процесс, а целая группа процессов, у каждого из которых есть несколько потоков. Всё это обеспечивает быстрое выполнение скриптов.
1. Установка компонентов
Сервис php-fpm поставляется вместе с интерпретатором php. Установка php-fpm Ubuntu выполняется такой командой:
sudo apt install php-fpm
Кроме того нам понадобится веб-сервер Nginx, потому что php-fpm чаще всего используется вместе с этим веб-сервером:
sudo apt install nginx
2. Конфигурационные файлы
В этой инструкции мы будем рассматривать настройку PHP-FPM на примере Ubuntu. Основной конфигурационный файл находится в такому пути:
Обратите внимание, что это не php.ini файл, а файл настройки именно FPM процессов. Файл php.ini находится в этой же папке:
А вот файлы конфигурации пулов находятся в каталоге /etc/php/7.4/fpm/pool.d/. По умолчанию там находится файл пула по умолчанию www.conf:
Вы можете использовать его в своей конфигурации или копировать для создания новых пулов.
3. Создание пула
Скопируйте файл пула, например losst.conf в папке /etc/php/7.4/fpm/pool.d/ скопируйте в него содержимое файла www.conf. В конце статьи я приведу полностью рабочий конфигурационный файл, но лучше всё же использовать конфигурацию вашей версии PHP:
cp /etc/php/7.4/fpm/pool.d/www.conf /etc/php/7.4/fpm/pool.d/losst.conf
Теперь откройте этот файл в текстовом редакторе, например в vim:
sudo vi /etc/php/7.4/fpm/pool.d/losst.conf
Далее надо изменить группу и пользователя, от имени которых будут запускаться процессы пула. Это важно, поскольку у процесса должен быть доступ к файлам PHP, которые надо выполнить. Обычно в Ubuntu для таких целей используется пользователь и группа www-data. От имени этого же пользователя обычно запускается веб-сервер:
Обычно, если вы получаете ошибку permission denied при интерпретации php файлов в php-fpm, означает, что процесс php-fpm запущен от имени не того пользователя или включена строгая политика SELinux.
4. Настройка сокета
Если вы используйте файловый сокет, к нему должен быть доступ у веб-сервера, поэтому надо сделать владельцами файла того пользователя и группу, от имени которых запущен веб-сервер, в данном случае www-data и дать им все права на него:
listen.owner = www-data
listen.group = www-data
listen.mode = 0660
Если сокет сетевой, то в этом нет необходимости. Для сетевого сокета можно дополнительно указать с каких адресов можно к нему подключаться. Например, только от 127.0.0.1:
5. Настройка процессов
С помощью параметра pm можно настроить сколько дочерних процессов будет запускаться для этого пула и когда. Есть три режима работы:
Режим static не выгоден, потому что вне зависимости от нагрузки потребляется много памяти и процессорного времени на поддержание работы процессов. Более интересны режимы ondemand и dynamic. Давайте будем использовать режим dynamic. Этот режим имеет три настройки:
Для режима static надо указать только pm.max_children. Для режима ondemand кроме pm.max_children надо указать pm.process_idle_timeout этот параметр означает через какой промежуток времени простоя процесс будет завершен.
Давайте разберемся с режимом dynamic. Запускать много дочерних процессов при старте не надо, в большинстве случаев 2-3 будет достаточно:
Минимальное количество процессов в режиме ожидания тоже большое не нужно, это запас, чтобы php-fpm смог быстро обработать новые запросы не тратя время на запуск новых процессов. Однако это значение должно быть не меньше pm.start_servers, иначе ничего не заработает:
Максимальное количество процессов определяет как быстро процессы будут завершаться при падении нагрузки, можно оставить 10 процессов:
Параметр pm.max_children настройте под себя, обычно достаточно 20-30 процессов, но всё зависит от нагрузки и количества оперативной памяти, если памяти мало лучше пожертвовать производительностью и установить меньшее значение:
Почти готово. Но есть ещё одна проблема. Если дочерние процессы работают слишком долго, в них накапливаются утечки памяти, и рано или поздно на сервере память закончится. Чтобы этого избежать можно настроить автоматическое завершение процесса после выполнения определённого количества запросов, например, 1000:
6. Настройка статистики
Для подбора оптимального значения pm.max_children вам может понадобиться посмотреть статистику в реальном времени сколько процессов запущено, сколько из них находится в ожидании, а также какая длина очереди ожидающих выполнения запросов. Для включения вывода статистики просто добавьте такую строчку:
7. Настройка php.ini
php_admin_flag[display_errors] = off
php_admin_value[error_log] = /var/log/fpm-php.losst.log
php_admin_flag[log_errors] = on
php_admin_value[memory_limit] = 32M
Когда все настройки завершены, не забудьте сохранить изменения и перезапустить php-fpm:
sudo systemctl restart php7.4-fpm
8. Настройка веб-сервера
Для того чтобы всё протестировать придётся настроить ещё и веб-сервер. В конфигурационный файл виртуального хоста Nginx надо добавить такие строки:
Последняя директива fastcgi_pass указывает как надо передавать данные php-fpm, сюда можно передать путь к файлу сокету, на котором слушает сервис или IP адрес и порт. В данном случае используется ранее настроенный 127.0.0.1:9000. После завершения настройки перезапустите Nginx:
sudo systemctl restart nginx
Теперь вы можете открыть в браузере страницу статистики, как видите всё работает:
Можно ещё создать файл phpinfo.php с текстом в каталоге веб-сервера и посмотреть настройки php, например, memory_limit, заданный в файле конфигурации пула работает:
Настройка веб-сервера может очень сильно отличаться в зависимости от ваших требований. Здесь приведен только общий пример, чтобы проверить работоспособность и верность настройки.
PHP-FPM — менеджер процессов PHP FastCGI
PHP-FPM — это альтернативная реализация PHP FastCGI с несколькими дополнительными возможностями, которые обычно используются для высоконагруженных сайтов.
FastCGI, PHP и PHP-FPM
FastCGI это высокопроизводительный и масштабируемый интерфейс для взаимодействия web-сервера и приложений, дальнейшее развитие технологии CGI. Основное преимущество FastCGI в изолировании динамического языка от web-сервера — запуск FastCGI процесса возможен под пользователем, отличным от пользователя web-сервера, а также процесс может находиться в chroot’е, отличном от chroot’а web-сервера. Помимо всего прочего, эта технология позволяет запускать web-сервера и CGI процессы (php скрипты, в случае php-fpm) на различных хостах, что улучшает масштабируемость и также способствует безопасности без существенной потери в производительности.
PHP «умеет» работать в режиме FastCGI и без PHP-FPM, но PHP-FPM устраняет ряд проблем мешающих использовать PHP в режиме FastCGI на высоконагруженных системах.
PHP-FPM — это:
Использование PHP-FPM
Наиболее часто используется связка nginx и PHP-FPM, которая работает эффективнее «классического» использования Apache с mod_php, а в ряде случаев показывает более высокую производительность, нежели более «продвинутое» использование в качестве фронтенда веб-сервера nginx, а в качестве бекенда — Apache с mod_php.
Язык программирования PHP
PHP — язык программирования, который наиболее распространён в сфере веб-разработки.
В сфере создания динамических веб-сайтов и веб-приложений PHP занимает значительную долю рынка. Практически все популярные CMS для веб-разработки написаны на PHP. Наиболее важные преимущества PHP — простота освоения, адекватная скорость работы, мультипарадигмальность. Критикуют PHP обычно за низкий средний уровень разработчиков и, как следствие, за низкую культуру разработки, проблемы с сопровождаемостью и надёжности проектов.
PHP — язык для веб-разработки, который можно назвать основным для «масс-маркета», то есть для разработки типовых сайтов на коробочных CMS.
PHP — скриптовый язык общего назначения, часто применяемый для разработки веб-сайтов.
PHP — интерпретируемый язык программирования, позволяющий создавать программы в процедурном и объектно-ориентированном стиле. PHP — хороший язык для разработки проектов на CMS. И c технической точки зрения современный PHP весьма неплох. Но экосистема языка и особенности кадрового рынка делают PHP не самым лучшим выбором для разработки сложных проектов.
Менеджер процессов FastCGI (FPM)
Содержание
FPM (FastCGI Process Manager, менеджер процессов FastCGI) является альтернативной реализацией PHP FastCGI с несколькими дополнительными возможностями обычно используемыми для высоконагруженных сайтов.
Эти возможности включают в себя:
продвинутое управление процессами с корректной (graceful) процедурой остановки и запуска;
возможность запуска воркеров с разными uid/gid/chroot/окружением, а также запуска на различных портах с использованием разных php.ini (замещение safe_mode);
логирование стандартных потоков вывода (stdout) и ошибок (stderr);
аварийный перезапуск в случае внезапного разрушения opcode-кеша;
поддержка ускоренной загрузки (accelerated upload);
Динамическое/статическое порождение дочерних процессов;
Базовая информация о статусе SAPI (аналогично Apache mod_status);
Конфигурационный файл, основанный на php.ini.
User Contributed Notes 8 notes
You will probably want to create an init script for your new php-fpm. Fortunately, PHP 5.3.3 provides one for you, which you should copy to your init directory and change permissions:
/sapi/fpm/init.d.php-fpm.in /etc/init.d/php-fpm
$ chmod 755 /etc/init.d/php-fpm
It requires a certain amount of setup. First of all, make sure your php-fpm.conf file is set up to create a PID file when php-fpm starts. E.g.:
—-
pid = /var/run/php-fpm.pid
—-
(also make sure your php-fpm user has permission to create this file).
Now open up your new init script (/etc/init.d/php-fpm) and set the variables at the top to their relevant values. E.g.:
—
prefix=
exec_prefix=
php_fpm_BIN=/sbin/php-fpm
php_fpm_CONF=/etc/php-fpm.conf
php_fpm_PID=/var/run/php-fpm.pid
—
Your init script is now ready. You should now be able to start, stop and reload php-fpm:
$ /etc/init.d/php-fpm start
$ /etc/init.d/php-fpm stop
$ /etc/init.d/php-fpm reload
The one remaining thing you may wish to do is to add your new php-fpm init script to system start-up. E.g. in CentOS:
$ /sbin/chkconfig php-fpm on
Disclaimer: Although I did just do this on my own server about 20 mins ago, everything I’ve written here is off the top of my head, so it may not be 100% correct. Also, allow for differences in system setup. Some understanding of what you are doing is assumed.
Nginx, Php-Fpm и что это вообще?
FPM
SAPI, он же Server API. В php есть несколько таких API для разных вариантов его работы:
Во вторую очередь, FPM действительно умный менеджер процессов. Он контролирует количество работающих PHP-процессов, частоту их перезапуска для борьбы с утечками памяти (да, модули php как и всегда текут) и прочие простые вещи, необходимые для контроля сервера.
Один процесс одновременно обрабатывает один запрос. Это абсолютно так же свойственно для PHP-FPM, как и для Apache.
Количество процессов определяет, сколько одновременно может «висеть» запросов в обработке.
NGINX
Благодаря этой архитектуре nginx на порядки быстрее обрабатывает запросы, чем любой другой сервер и благодаря ей же потребляет при этом сильно меньше ресурсов. Как это происходит?
В эту схему отлично вписалась асинхронная работа со статическими файлами. Благодаря тому, что в современном мире с файлами можно работать почти так же асинхронно, как и с backend, Nginx отлично разделяет работу на две части: статику отдает с диска, динамику обрабатывает в PHP-FPM.
В чем выигрыш?
У вас на странице 100 картинок+js+css-ок? Значит, большая их часть будет висеть в очереди внутри сервера Apache и ждать, когда пользователь получит предыдущие 35 ответов.
В случае с Nginx + PHP-FPM важнее всего количество процессов PHP-FPM. Мы можем поставить его таким же равным тридцати пяти. Что это значит? Это значит, что мы можем одновременно обрабатывать 35 запросов к динамике, запросы же к статике nginx разгребет своими силами в количестве 3000+ одновременных почти на любой слабой VPS.
Расход оперативной памяти при использовании Nginx+PHP-FPM меньше, чем на «голом» Apache, при равном количестве процессов (FPM и Apache). Скорость обработки запросов выше.
На расход CPU внутри PHP замена Apache на FPM никак не скажется. CPU в первую очередь кушает Ваш PHP-код, а пока его никто не оптимизирует, работать быстрее и экономичнее он не начнет.
Итог
Все проблемы PHP (процесс на запрос, не оптимальный код самого проекта) никуда не деваются.
Появляется возможность перелопачивать тонны запросов за статикой, которой нет в Apache.
Вы экономите оперативную память, что сказывается на цене оборудования или VPS.
Появляется море приятного функционала самого Nginx.
Пропадает возможность использовать htaccess, но честно скажу, конфигурация nginx куда более простая и понятная, чем htaccess.
Установка PHP и модулей на Ubuntu/Debian
В Debian/Ubuntu это делается легко и просто, зачастую не требуется ничего собирать
Капризы WebSocket и при чём здесь костыли
Протокол WebSocket имеет свои преимущества и свои недостатки: детальный разбор
Curl в PHP
Почему timeout для curl в php необходим
IoT Highload: особенности и подводные камни
Особенности серверных приложений, работающих с сетью IoT-устройств на практике и в теории
Установка PHP и модулей на Ubuntu/Debian
В Debian/Ubuntu это делается легко и просто, зачастую не требуется ничего собирать
Капризы WebSocket и при чём здесь костыли
Протокол WebSocket имеет свои преимущества и свои недостатки: детальный разбор
Curl в PHP
Почему timeout для curl в php необходим
IoT Highload: особенности и подводные камни
Особенности серверных приложений, работающих с сетью IoT-устройств на практике и в теории
О безопасности, рисках и вложениях
Как сделать так, чтобы Ваш IT-отдел не стал местом утечки информации, за которую Вы отвечаете?