Конфигурация пула php-fpm

Конспект в доработке

    Параметры php-fpm

    Полный список директив: https://www.php.net/manual/en/install.fpm.configuration.php


    [www] - имя пула, обязательный параметр

    user и group - Имя и группа, от имени которых будут работать процессы
    user = www-data
    group = www-data

    listen - Файл unix сокета или tcp/ip сокета для прослушивания запросов от веб-сервера
    listen = 127.0.0.1:9000

    listen.backlog - размер очереди одновременно ожидающих подключений к сокету listen.backlog = 100
    Если значение большое, а PHP-FPM не успевает обрабатывать все запросы, то веб-сервер дождется тайм-аута и отключится, выкинув 504 ошибку (Gateway Timeout, Шлюз не отвечает). Если значение маленькое, то клиентские запросы вообще не могут попасть в очередь и веб-сервер сразу выдает 502 ошибку (Bad Gateway, Неправильный шлюз)

    listen.owner, listen.group, listen.mode - разрешения для unix-сокета, если он используется. В Linux необходимо установить доступ на чтение и запись, чтобы разрешить подключение с веб-сервера
    listen.owner = www-data
    listen.group = www-data
    listen.mode = 0660

    listen.allowed_clients - Список ip-адресов, которым разрешено подключение. Адреса разделяются запятыми. Имеет смысл только с tcp/ip сокетом
    listen.allowed_clients = 127.0.0.1

    pm.status_path - URI страницы статуса службы PHP-FPM
    pm.status_path = /php-fpm-status

    pm.status_listen - Значением может быть unix сокет или tcp/ip сокет, по которому будет приниматься запрос состояния. Создаёт новый невидимый пул, который может независимо обрабатывать запросы. Полезно, если основной пул занят долго выполняющимися запросами, так как всё ещё можно получить страницу состояния PHP-FPM до завершения долго выполняющихся запросов. Значение по умолчанию — как у директивы listen.
    pm.status_listen = 127.0.0.1:9001

    ping.path - URI страницы мониторинга службы PHP-FPM. Если значение не установлено, ping-страница отображаться не будет. Можно использовать для тестирования извне, чтобы убедиться, что служба PHP-FPM работает и отвечает.
    ping.path = /php-fpm-ping

    ping.response - Директива предназначена для настройки ответа на ping-запрос. Ответ формируется как text/plain со кодом ответа 200. Значение по умолчанию — pong.
    ping.response = pong

    access.log - Путь к файлу лога доступа. Префикс по умолчанию для относительного пути — /usr. Значение по умолчанию — не установлено
    access.log = /var/log/$pool.php-fpm.access.log

    slowlog - Путь к файлу лога медленных запросов
    slowlog = /var/log/$pool.php-fpm.slow.log

    request_slowlog_timeout - Время ожидания в секундах на обработку одного запроса, после чего PHP backtrace будет сохранён в файл slowlog

    request_slowlog_trace_depth - Глубина трассировки стека вызовов для журнала slowlog

    request_terminate_timeout - ремя ожидания в секундах на обработку одного запроса, после чего рабочий процесс будет принудительно завершён. Этот вариант следует использовать, когда опция max_execution_time в файле php.ini не останавливает выполнение скрипта по каким-то причинам

    catch_workers_output - Перенаправляет stdout и stderr дочерних процессов в основной журнал ошибок. Если задано значение no — stdout/stderr будут перенаправлены в /dev/null. Значение по умолчанию — no.
    catch_workers_output = yes

    decorate_workers_output - Дополняет информацию от дочерних процессов для записи в основной журнал ошиблк. Имеет смысл только если catch_workers_output=yes
    decorate_workers_output = yes

    emergency_restart_threshold - Если кол-во дочерних процессов, которые завершились по сигналам SIGSEGV или SIGBUS, превышает указанное значение, то служба PHP-FPM будет перезапущена. Значение по умолчанию 0 (выкл)

    emergency_restart_interval - Интервал времени в секундах, в течение которого должны завершиться дочерние процессы по сигналам SIGSEGV или SIGBUS, чтобы служба PHP-FPM была перезапущена. По умолчанию 0 (выкл)

    process_control_timeout - задает интервал времени в секундах, в течение которого master-ппоцесс будет ждать корректного завершения рабочего процесса, прежде чем принудительно завершить его. Значение по умолчанию — 0 (без ограничений)

    process.max - Максимальное кол-во дочерних процессов, которое может запустить служба PHP-FPM. Это нужно для контроля глобального количества процессов при использовании dynamic в большом количестве пулов, по умолчанию значение 0 (без ограничений)

    process.priority - Указывает приоритет (nice) мастер-процесса ( по умолчанию не установлен )

    daemonize - запустить PHP-FPM в фоновом режиме. Чтобы запустить PHP-FPM для отладки — нужно установить значение no. По умолчанию — yes

    systemd_interval - Если PHP-FPM собран с интеграцией с Systemd, указывает интервал в секундах между оповещениями Systemd о своём состоянии

    include=/etc/php/8.1/fpm/pool.d/*.conf - Подключить все файлы конфигурации пулов процессов из директории pool.d

    Настройки производительности php-fpm

    Параметр pm в PHP позволяет настроить, как менеджер процессов будет контролировать создание дочерних процессов


    pm = dynamic — количество дочерних процессов настраивается динамически на основе директив: pm.max_children, pm.start_servers,pm.min_spare_servers, pm.max_spare_servers
    PHP-FPM динамически регулирует количество доступных дочерних процессов и гарантирует постоянную доступность хотя бы одного из них
    Режим dynamic задействует 5 параметров: pm.max_children, pm.start_servers, pm.min_spare_servers, pm.min_spare_servers, pm.max_spare_servers, pm.process_idle_timeout
    При использовании pm.dynamic важную роль играют параметр min_spare_servers, так и параметр max_spare_servers, веб-трафик сильно меняется и у него есть высокие пики и глубокие спады
    В режиме dynamic можно в итоге получить конфигурацию, которая по сути копирует static
    Такой режим больше всего подходит, когда нужна экономия ресурсов (за счет уменьшения дочерних процессов при простое), но при этом бывают пиковые всплески, которые необходимо обработать.

    pm = ondemand — процессы создаются по требованию (в отличие от динамического создания, когда pm.start_servers запускаются при запуске сервиса)
    ondemand заставляет PHP-FPM форкать процессы при получении запросов
    Режим ondemand завершает бездействующие процессы до нуля, когда трафика мало или нет вообще
    Данный режим использует параметры: max_children, process_idle_timeout, max_requests
    Возможно следует использовать именно этот режим при нехватке оперативной памяти
    Режим ondemand чаще всего выбирают для сайта с низким трафиком, поскольку дочерние процессы будут создаваться только по необходимости, и завершаться, когда они больше не нужны
    С одной стороны — не будет запущено лишних процессов, с другой стороны — клиентам придётся подождать запуска процесса

    pm = static — количество дочерних процессов фиксировано и указывается параметром pm.max_children
    Static гарантирует, что обработка пользовательских запросов всегда доступна фиксированному количеству дочерних процессов
    В данном режиме часть процессов будут бездействовать, даже при небольшой активности пользователей. Простаивающие процессы ждет пиков трафика и реагирует моментально.
    Не нужно ждать пока pm создаст дочерние процессы, а потом завершит их, когда истечет период pm.process_idle_timeout
    Режим static следует выбирать для сайта с высоким трафиком, где требуется как можно меньшее время ответа, когда есть постоянная высокая нагрузка и большой объём памяти

    Параметр PHP-FPM pm static во многом зависит от свободной памяти на сервере. Если памяти мало, лучше выбрать ondemand или dynamic

    pm.max_children - число дочерних процессов, которые будут созданы, когда pm установлен в static или максимальное число процессов, которые будут созданы, когда pm установлен в dynamic. Устанавливает ограничение на число одновременных запросов, которые будут обслуживаться
    Значение pm.max_children следует устанавливать таким образом чтобы перегрузить процессоры и накопить кучу операций PHP-FPM, ожидающих выполнения. Память и процессор будут работать без чрезмерной перегрузки
    Если значение слишком маленькое, при возрастании нагрузки лимит исчерпается и сайт начнёт тупить. Если значение слишком большое, исчерпается оперативная память

    pm.max_spare_servers - определяет максимальное количество процессов в состоянии ожидания
    Если нет нагрузки на приложение, PHP-FPM удалит лишние процессы с целью сохранить оперативную память.
    Значение примерно будет соответствовать значению pm.start_servers. Рекомендуется установить значение примерно 75% от pm.max_children

    pm.start_servers помогает гарантировать постоянную доступность хотя бы одного из дочерних процессов, что важно в режиме dynamic, когда нужна экономия ресурсов, но при этом бывают пиковые всплески, которые необходимо обработать
    pm.start_servers - используется, только когда pm установлен в dynamic. Значение по умолчанию рассчитывается по формуле min_spare_servers + (max_spare_servers - min_spare_servers) / 2
    Значение будет равно - количество ядер процессора х 4. Рекомендуется установить значение pm.start_servers примерно 50% от pm.max_children.

    pm.min_spare_servers — минимальное количество процессов в режиме ожидания (ничего не обрабатывающих) в настройках сервиса PHP-FPM. Если количество процессов меньше, будет создан ещё один. Данный запас нужен, чтобы PHP-FPM смог быстро обработать новые запросы, не тратя время на запуск новых процессов и должен быть меньше чем max_spare_servers
    Значение будет равно: количество ядер процессора х 2
    Рекомендуется установить значение в 25% от pm.max_children
    Используется только для dynamic

    max_requests - это максимальное количество запросов, которое обработает дочерний процесс, прежде чем будет уничтожен

    pm.process_idle_timeout — это параметр конфигурации PHP-FPM, который указывает время простоя в секундах, по истечении которого дочерний процесс будет убит. Эта настройка помогает освободить ресурсы, когда они не активно обслуживают запросы

    Лучший способ определить max_children — выяснить, сколько памяти использует каждый дочерний процесс, затем разделить максимально доступный объём оперативной памяти, на память одного процесса
    Узнать сколько памяти в среднем потребляет дочерний процесс php-fpm, можно с помощью команды:
    sudo ps aux --sort=rss -u www-data | grep -e php-fpm -e RSS
    Например размер оперативной памяти 50 ГБ, из который на php-fpm можно потратить только 30 Гб.
    Cредний размер выделяемой памяти на один процесс составляет 150 Мб
    Тогда max_children будет примерно равен 200 процессов

    pm = dynamic
    max_children = 200
    pm.max_spare_servers = 150
    pm.start_servers = 75
    pm.min_spare_servers = 40
    max_requests = 500
    Данный расчет примерный, и зависит от пиковой нагрузки на сервер, возможно правильно будет оставить определенный запас дочерних процессов на случай резкого увеличения трафика
    Рекомендуется постепенно настраивать параметры, тестируя и корректируя значения на каждом шаге в разные периоды времени работы веб-сервера

    Приложение можно разделить на несколько частей с использованием разных пулов
    Например для обслуживания фронтенда и бекэнда, можно использовать разные пулы. Оба будут иметь одного и того же пользователя и группу, но иметь разные конфигурации менеджера процессов и подключены через разные сокеты.
    Настройки php-fpm:

    #/etc/php/8.1/fpm/pool.d/www.conf ; frontend [frontend] listen = /var/run/php-fpm-frontend.sock user = www-data group = www-data listen.owner = www-data listen.group = www-data pm = static pm.max_children = 5 ; backend [backend] listen = /var/run/php-fpm-backend.sock user = www-data group = www-data listen.owner = www-data listen.group = www-data pm = ondemand pm.max_children = 5 pm.process_idle_timeout = 10s

    Настройки nginx:

    server { listen 80; server_name test-site.localdomain; root /var/www/test-site/public; access_log /var/log/nginx/test-site.access.log; error_log /var/log/nginx/test-site.error.log error; index index.php; set $fpm_socket "unix:/var/run/php-fpm-frontend.sock"; if ($uri ~* "^/api/") { set $fpm_socket "unix:/var/run/php-fpm-backend.sock"; } location / { try_files $uri $uri/ /index.php; location ~ .php$ { fastcgi_split_path_info ^(.+.php)(/.+)$; fastcgi_pass $fpm_socket; fastcgi_index index.php; include fastcgi.conf; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; } } }

    Это создаст конфигурацию виртуального хоста, которая отправляет запросы в пул фронтенда или бэкенда в зависимости от запрошенной локации


    RSS (Resident Set Size) — это резидентная память, которая показывает, сколько физической памяти занято процессом в момент вывода команды. Она не включает память, которая заменяется. RSS содержит динамические библиотеки, с которыми связан процесс и которые загружены в физическую память. Также в неё входит память стека и кучи

    VSZ (Virtual Memory Size) — это виртуальная память. Она содержит всю память, к которой может получить доступ процесс, включая память, которая заменяется, память, которая выделена, но ещё не используется, и память из разделяемых библиотек

    RSS показывает, сколько памяти используется процессом, VSZ — всю память, к которой процесс может получить доступ

    #Просмотреть все процессы php-fpm из вывода команды top
    top -bn1 | grep php-fpm #Примерно тот же результат покажет команда ps #В данном случае будут показаны процессы запущенные от пользователя www-data #Процессы будут отсортированы по объему резидентной памяти RSS ps aux --sort=rss -u www-data | grep -e php-fpm -e RSS | wc -l #Чтобы проверить результат внесенных изменений запустите #Из вывода можно будет увидеть, что доступно ... процессов pstree -c -H -S

    Каждый дочерний процесс способен обрабатывать, к примеру, один запрос к приложению за раз
    Если для параметра max_children установлено значение 5, а запросов 10, скорее всего, в логах появится что-то вроде этого:
    WARNING: [pool www] server reached pm.max_children setting (5), consider raising it
    Это приведёт к тому, что некоторые запросы будут отложены пока не освободится достаточное количество дочерних процессов
    Самый простой способ получить текущие значения настроек PHP-FPM без чтения файла конфигурации — использовать эту команду:

    #Вывод настроек для каждого пула php-fpm82 -tt [09-Jan-2025 14:33:12] NOTICE: [www] [09-Jan-2025 14:33:12] NOTICE: prefix = undefined [09-Jan-2025 14:33:12] NOTICE: user = www-data [09-Jan-2025 14:33:12] NOTICE: group = www-data [09-Jan-2025 14:33:12] NOTICE: listen = /var/run/php-fastcgi.sock [09-Jan-2025 14:33:12] NOTICE: listen.backlog = -1 [09-Jan-2025 14:33:12] NOTICE: listen.acl_users = undefined [09-Jan-2025 14:33:12] NOTICE: listen.acl_groups = undefined [09-Jan-2025 14:33:12] NOTICE: listen.owner = www-data [09-Jan-2025 14:33:12] NOTICE: listen.group = www-data [09-Jan-2025 14:33:12] NOTICE: listen.mode = 0660 [09-Jan-2025 14:33:12] NOTICE: listen.allowed_clients = 127.0.0.1 [09-Jan-2025 14:33:12] NOTICE: process.priority = undefined [09-Jan-2025 14:33:12] NOTICE: process.dumpable = no [09-Jan-2025 14:33:12] NOTICE: pm = static [09-Jan-2025 14:33:12] NOTICE: pm.max_children = 100 [09-Jan-2025 14:33:12] NOTICE: pm.start_servers = 5 [09-Jan-2025 14:33:12] NOTICE: pm.min_spare_servers = 5 [09-Jan-2025 14:33:12] NOTICE: pm.max_spare_servers = 17 [09-Jan-2025 14:33:12] NOTICE: pm.max_spawn_rate = 32 [09-Jan-2025 14:33:12] NOTICE: pm.process_idle_timeout = 10 [09-Jan-2025 14:33:12] NOTICE: pm.max_requests = 100 [09-Jan-2025 14:33:12] NOTICE: pm.status_path = /status-www [09-Jan-2025 14:33:12] NOTICE: pm.status_listen = undefined [09-Jan-2025 14:33:12] NOTICE: ping.path = undefined [09-Jan-2025 14:33:12] NOTICE: ping.response = undefined [09-Jan-2025 14:33:12] NOTICE: access.log = undefined [09-Jan-2025 14:33:12] NOTICE: access.format = undefined [09-Jan-2025 14:33:12] NOTICE: slowlog = /var/log/php-fpm.log.slow [09-Jan-2025 14:33:12] NOTICE: request_slowlog_timeout = 0s [09-Jan-2025 14:33:12] NOTICE: request_slowlog_trace_depth = 20 [09-Jan-2025 14:33:12] NOTICE: request_terminate_timeout = 0s [09-Jan-2025 14:33:12] NOTICE: request_terminate_timeout_track_finished = no [09-Jan-2025 14:33:12] NOTICE: rlimit_files = 0 [09-Jan-2025 14:33:12] NOTICE: rlimit_core = 0 [09-Jan-2025 14:33:12] NOTICE: chroot = undefined [09-Jan-2025 14:33:12] NOTICE: chdir = / [09-Jan-2025 14:33:12] NOTICE: catch_workers_output = no [09-Jan-2025 14:33:12] NOTICE: decorate_workers_output = yes [09-Jan-2025 14:33:12] NOTICE: clear_env = yes [09-Jan-2025 14:33:12] NOTICE: security.limit_extensions = .php .phar [09-Jan-2025 14:33:12] NOTICE: [09-Jan-2025 14:33:12] NOTICE: configuration file /etc/php82/php-fpm.conf test is successful

    Если было порождено слишком много дочерних процессов, все они используются, и на сервере для них просто не хватает памяти. Если после перезапуска PHP-FPM использование памяти падает, а затем постепенно возрастает до предела, это свидетельствует об утечке памяти в коде приложения, иначе говоря после отработки скриптов, память у процессов не освобождается
    Если дочерних процессов слишком много, на сервере для них может не хватать памяти.
    Несколько процессов могут и обычно будут совместно использовать часть памяти, поэтому трудно точно определить реальное использование памяти одним процессом
    Чтобы вычислить общий объем памяти, используемый программой, можно использовать скрипт python

    wget https://raw.githubusercontent.com/pixelb/ps_mem/master/ps_mem.py chmod a+x ps_mem.py sudo python3 ps_mem.py Private + Shared = RAM used Program 2.4 MiB + 2.5 MiB = 5.0 MiB sshd (7) 5.5 MiB + 3.6 MiB = 9.2 MiB nginx (4) 21.6 MiB + 57.5 KiB = 21.7 MiB memcached 25.9 MiB + 3.5 KiB = 25.9 MiB telegram 28.6 MiB + 27.5 KiB = 28.6 MiB bundle 34.8 MiB + 2.0 MiB = 36.8 MiB beam.smp 19.1 MiB + 32.6 MiB = 51.7 MiB postgres (9) 1.7 GiB + 78.7 MiB = 1.8 GiB php-fpm82 (108) --------------------------------- 2.0 GiB =================================

    Строка:
    1.7 GiB + 78.7 MiB = 1.8 GiB php-fpm82 (108)
    означает, что 108 процессов PHP-FPM используют 1.8 ГБ памяти. Один процесс использует около 16 МБ


    Другая полезная команда позволяет определить определить количество незадействованных и активных процессов используя значение pm.status_path

    # curl localhost/status-www pool: www process manager: static start time: 08/Jan/2025:20:05:08 +0300 start since: 66660 accepted conn: 796 listen queue: 0 max listen queue: 0 listen queue len: 0 idle processes: 99 active processes: 1 total processes: 100 max active processes: 34 max children reached: 0 slow requests: 0

    listen queue: - Количество запросов (backlog), ожидающих свободного процесса
    max listen queue - Максимальное количество запросов в очереди на прослушивание в любой момент времени
    listen queue len - Максимально допустимый размер очереди прослушивания
    idle processes Количество процессов, которые в настоящее время простаивают (ожидают запросов)
    active processes Количество процессов, которые в настоящее время обрабатывают запросы
    total processes Текущее общее количество процессов
    max active processes Максимальное количество одновременно активных процессов
    max children reached Было ли достигнуто максимальное количество процессов? Если да, то отображаемое значение будет больше или равно 1, иначе значение будет равно 0
    slow requests Общее количество запросов, которые достигли настроенного request_slowlog_timeout
    memory peak Пиковое значение объёма памяти, которую PHP выделил с момента запуска FPM-менеджера процессов


    99 бездействующих процессов

    Если происходит утечка памяти, память для одного процесса может заполниться до значения memory_limit, определённого в файле php.ini, по умолчанию это 128 MB. Для подстраховки можно использовать это значение как среднее для одного процесса PHP-FPM

    Источник: https://www.dev-notes.ru/articles/devops/a-deeper-dive-into-optimal-php-fpm-settings/

    Подробная статистика

    Если нужна подробная статистика по состоянию процесса php-fpm, можно передать аргумент ?full

    # curl localhost/status-www?full pool: www process manager: dynamic start time: 09/Jan/2025:20:19:43 +0300 start since: 41742 accepted conn: 741 listen queue: 0 max listen queue: 0 listen queue len: 0 idle processes: 13 active processes: 1 total processes: 14 max active processes: 6 max children reached: 0 slow requests: 0 ************************ pid: 24584 state: Idle start time: 09/Jan/2025:20:19:43 +0300 start since: 41742 requests: 54 request duration: 322756 request method: - request URI: - content length: 0 user: - script: - last request cpu: 86.75 last request memory: 41943040 ************************

    pid Системный PID-идентификатор процесса
    state Состояние процесса — Idle, Running
    start time Дата и время начала процесса
    start since Количество секунд с момента начала процесса
    requests Общее количество обслуженных запросов
    request duration Общее время в микросекундах, затраченное на обслуживание последнего запроса
    request method Метод HTTP последнего обслуженного запроса
    request uri URI-идентификатор последнего обслуженного запроса (после обработки веб-сервером он всегда может быть равен /index.php, если вы используете шаблонный редирект фронт-контроллера)
    content length Длина тела запроса, в байтах, последнего запроса
    user HTTP-пользователь (PHP_AUTH_USER) последнего запроса
    script Полный путь к скрипту, который выполнил последний запрос. Это будет '-', если не применимо (например, запросы страницы состояния)
    last request cpu Процент занятого центральным процессором времени при выполнении последнего запроса. Это значение будет равно 0, если процесс не в состоянии Idle, потому что вычисление проводится после окончания обработки запроса. Значение может превысить 100 %, потому что метрика покажет, какой процент от общего времени работы процессора занял последний запрос, — в расчёте менеджер учтёт процессы на каждом ядре, тогда как 100 % — это значение только для одного ядра
    last request memory Максимальный объем памяти, который потребил последний запрос. Это значение будет равно 0, если процесс не простаивает, поскольку вычисление проводится после окончания обработки запроса


    Источник: https://www.php.net/manual/ru/fpm.status.php

    Особенности использования режима Dynamic

    Предположим, что в конфигурации пула используются следующие значения:
    pm = dynamic
    pm.max_children = 70
    pm.start_servers = 20
    pm.min_spare_servers = 20
    pm.max_spare_servers = 40


    В данном случае при запуске порождается 20 дочерних процессов, которые занимают память обычно используемую 20-ю процессами
    Если к приложению поступают запросы, некоторые или все эти процессы будут активны и обрабатывать запросы
    Если запросов не будет, тогда 20 этих процессов не будут завершены и будут по прежнему потреблять память
    Устанавливать min_spare_servers меньшее, чем start_servers (например, 15), не имеет смысла, поскольку 20 дочерних процессов будут порождены немедленно, и даже если они будут простаивать, главный процесс не завершит 5 дочерних процессов, чтобы достичь этого минимума в 15. И не стоит задавать значение min_spare_servers больше, чем start_servers, поэтому лучшим вариантом, будет установка min_spare_servers равным значению start_servers
    Теперь, если поступает много запросов и 20 дочерних процессов не хватает для их обработки, главный процесс породит дополнительные дочерние процессы до значения max_children, т.е. до 70
    Через некоторое время ситуация нормализуется, и 70 процессов больше не нужны; большинство или все из них простаивают. В этом случае главный процесс завершит простаивающие дочерние процессы до значения max_spare_servers, в данном случае 40
    В итоге останется 40 простаивающих процессов, которые не будут завершены в дальнейшем и будут использовать память, которую использует 40 дочерних процессов
    Если нет необходимости получить 40 дочерних процессов, работающих в фоновом режиме, стоит уменьшить это значение или даже оставить его таким же, как start_servers
    После перезапуска снова будут порождены 20 дочерних процессов на основе start_servers

    Существует другая теория исходя из которой кол-во дочерних высчитывается по формулам:
    pm.start_servers = number of CPU cores x 4
    pm.min_spare_servers = number of CPU cores x 2
    pm.max_spare_servers = number of CPU cores x 4

    В данном следует учитывать не только ко-во ядер, однако в любом случае необходимо учитывать доступный размер оперативной памяти, размер выделенной памяти для одного процесса и др.

    Будет правильно, постепенно отслеживать и настраивать параметры пула учитывая изменение нагрузки на сервер

    Стоит обратить внимание еще на одну опцию pm.max_requests. Если есть утечка памяти, эта настройка может быть полезна для перезагрузки дочерних процессов после определённого количества запросов. Например, если установить значение 500, то после обработки 500 запросов дочерний процесс будет завершён (освободив таким образом всю накопленную память), а затем создан заново.

    Тестирование веб-сервера

    ApacheBench (ab) — однопоточная программа для командной строки, использующаяся для измерения производительности HTTP веб-серверов

    Дополнительные настройки

    С помощью опции slowlog можно отследить меделенные запросы
    Для активации необходимо добавить в настройки пула строку:

    slowlog = /var/log/php8.2-fpm.log.slow

    request_slowlog_timeout - запросы, занимающие, например, 3 секунды и более
    request_slowlog_trace_depth - это глубина трассировки стека вызовов для журнала slowlog. Значение по умолчанию — 20. Опция может быть полезна в том случае если необходимо узнать какой скрипт вызывается


    Другие настройки на которые следует обратить внимание хранятся в файле: /etc/php/8.2/fpm/php-fpm.conf

    #Первые две настройка говорят, что если 10 дочерних процессов не работают в течение одной минуты, #то PHP-FPM должен перезапуститься автоматически emergency_restart_threshold = 10 emergency_restart_interval = 1m #Дочерний процесс будет ждать 10 секунд, прежде чем действовать по сигналу, отправленному от главного процесса process_control_timeout = 10s

    error_log - Путь к файлу журнала ошибок


    log_level - Уровень журналирования ошибок (alert, error, warning, notice, debug)


    Источник1: https://www.dev-notes.ru/articles/devops/a-deeper-dive-into-optimal-php-fpm-settings/
    Источник2: https://www.php.net/manual/ru/install.fpm.configuration.php

    PHP настройки в файле nginx.conf

    Поскольку эти настройки передаются в php-fpm как FastCGI-заголовки, php-fpm не привязывают к адресу, который доступен из внешнего мира, иначе кто угодно изменит настройки PHP

    set $php_value "pcre.backtrack_limit=424242"; set $php_value "$php_value \n pcre.recursion_limit=99999"; fastcgi_param PHP_VALUE $php_value; fastcgi_param PHP_ADMIN_VALUE "open_basedir=/var/www/htdocs";
    Примечание


    Пулы — не механизм безопасности, поскольку не обеспечивают полного разделения; например пулы будут использовать один экземпляр OPcache

    php.ini
    #Время выполнения скрипта max_execution_time = 30 #Объем памяти выделенный скрипту memory_limit = -1 #задаёт максимальное время в секундах, #в течение которого скрипт должен разобрать все входные данные, #переданные запросами вроде POST или GET max_input_time = 60 #Лимит на объем загружаемого файла post_max_size = 8M upload_max_filesize = 2M #максимальное время ожидания (в секундах) для выполнения сетевых операций default_socket_timeout = 60 #pgsql.
    Примеры ошибок в логах PHP
    server reached pm.max_children setting (100), consider raising it

    Если кол-во дочерних процессов php-fpm больше максимально-допустимого кол-ва дочерних процессов ( pm.max_children, pm.start_servers,pm.min_spare_servers, pm.max_spare_servers ), тогда в логах php можно увидеть ошибки:
    [27-Dec-2024 10:05:48] WARNING: [pool www] seems busy (you may need to increase pm.start_servers, or pm.min/max_spare_servers), spawning 8 children, there are 0 idle, an d 98 total children
    [27-Dec-2024 10:05:49] WARNING: [pool www] server reached pm.max_children setting (100), consider raising it

    В логах nginx, который отправляет запросы к вышестоящему серверу php, возможно будет ошибки: upstream timed out (110: Operation timed out) while reading response header from upstream, client: 192.168.***.***, server: *************.ru, request: "GET **********:197 HTTP/2.0", upstream: "fastcgi://unix:/var/run/php-fastcgi.sock", host:
    В таком случае пользовательский веб-интерфейс будет тормозить или вовсе недоступен с ошибкой 504 в браузере
    Возможные причины и способы решения данной проблемы в Nginx описанны ниже ( Часто встречаемые ошибки в логах NGINX )
    Если изменение конфигурации php не устраняет проблемы, возможно, у вас просто недостаточно потоков/ядер процессора для обслуживания рабочих нагрузок PHP-FPM.


    Источники
    Последнее изменение: 10.01.2025 19:09


    Связанные темы
    Здесь пока нет комментариев
    Добавлять комментарии могут только авторизованные пользователи

    Авторизоваться
    Я буду рекламой
    Я тоже буду рекламой
    И я
    ВВЕРХ