Nginx php fpm worker

Советы по настройке и оптимизации Nginx и PHP-FPM

Thank you for reading this post, don’t forget to subscribe!

Определить Nginx worker_processes и worker_connections

Настрой­ки по умол­ча­нию хоро­ши, но их сто­ит немно­го опти­ми­зи­ро­вать: max_clients = worker_processes * worker_connections .

Базо­вые настрой­ки Nginx могут обра­ба­ты­вать сот­ни одно­вре­мен­ных соединений:

Обыч­но 1000 одно­вре­мен­ных соеди­не­ний на один сер­вер это хоро­шо, но порою дру­гие части, напри­мер жест­кий диск могут ока­зать­ся мед­лен­ны­ми и это при­ве­дет к тому, что Nginx будет забло­ки­ро­ван на опе­ра­ции вво­да-выво­да (I/O). Что­бы избе­жать бло­ки­ров­ки исполь­зуй­те, напри­мер, сле­ду­ю­щие настрой­ки: одни worker_process на ядро процессора :

Worker Processes

Что­бы опре­де­лить сколь­ко ядер име­ет ваш про­цес­сор, введите:

В дан­ном слу­чае у меня четы­ре ядра, поэто­му окон­ча­тель­ный пара­мерт worker_processes уста­нав­ли­ва­ем как 4:

Worker Connections

Лич­но я при­дер­жи­ва­юсь 1024 соеди­не­ний на один вор­кер, пото­му что у меня нет ника­ких осно­ва­ний для повы­ше­ния это­го зна­че­ния. Но если напри­мер 4096 соеди­не­ний в секун­ду не хва­та­ет, то мож­но попро­бо­вать удво­ить 2048 соеди­не­ний на процесс.

Окон­ча­тель­ные настрой­ки выгля­дят седу­ю­щим образом:

Скрыть токены Nginx / Скрыть номер версии Nginx

Это хоро­шо из сооб­ра­же­ний без­опас­но­сти — скрыть токе­ны Nginx и скрыть номер вер­сии Nginx, тем более если вы исполь­зу­е­те уста­рев­шую вер­сию Nginx. Это очень лег­ко сде­лать — доста­точ­но доба­вить в сек­цию http/server/location фай­ла кон­фи­гу­ра­ции сле­ду­ю­щую строку:

Ограничение на размер передаваемых данных сервером Nginx

Если вы хоти­те раз­ре­шить поль­зо­ва­те­лям загру­жать фай­лы, то вы долж­ны уве­ли­чить раз­мер сооб­ще­ния. Это может быть сде­ла­но с помо­щью зна­че­ния client_max_body_size , кото­рое нахо­дит­ся в сек­ции http/server/location фай­ла кон­фи­гу­ра­ции. По умол­ча­нию он равен 1 Мб, но его мож­но уве­ли­чить, напри­мер, до 20 Мб, а так­же уве­ли­чить раз­мер буфера:

Если вы полу­ча­е­те сооб­ще­ние об ошиб­ке, то вы зна­е­те, что client_max_body_size слиш­ком мало:

Управление кешем для статических файлов

Кэш бра­у­зе­ра сохра­нит ресур­сы и про­пуск­ную спо­соб­ность ваше­го сер­ве­ра. Это неслож­ная настрой­ка Nginx поз­во­лит выклю­чить веде­ние логов ( access log и not found log ), и уста­но­вить срок исте­че­ния заго­лов­ка в 360 дней.

Если вы хоти­те более слож­ный заго­лов­ки или дру­гие типы фай­лов, то вы може­те настро­ить их отдельно.

Проксируйте PHP запросы к PHP-FPM

Вы може­те исполь­зо­вать по умол­ча­нию стек tcp/ip или соеди­не­ние через Unix-сокет. Так­же необ­хо­ди­мо уста­но­вить PHP-FPM слу­шать точ­но такой же ip:port или Unix-сокет. Вот очень про­стой при­мер кон­фи­гу­ра­ции (вари­ант с Unix-соке­том закоментирован):

Это дает воз­мож­ность запус­ка PHP-FPM дру­гим сервером.

Предотвращение (запрет) доступа к скрытым файлам

Это очень рас­про­стра­не­но, когда корень сер­ве­ра или дру­гие пуб­лич­ные ката­ло­ги име­ют скры­тые фай­лы, кото­рые начи­на­ют­ся с точ­ки (.) И, как пра­ви­ло, они не пред­на­зна­че­ны для поль­зо­ва­те­лей сай­та. Пуб­лич­ный ката­лог может содер­жать фай­лы систе­мы кон­тро­ля вер­сий: .git , .svn ; фай­лы IDE : .idea ; .htaccess фай­лы. Настрой­ки запе­ща­ют доступ к скры­тым фай­лам и отклю­ча­ют веде­ние логов:

Советы по настройке и оптимизации PHP-FPM

Файлы конфигурации PHP-FPM

Обыч­но кон­фи­гу­ра­ции PHP-FPM рас­по­ло­жен­ны в фай­ле /etc/php-fpm.conf и в ката­ло­ге /etc/php-fpm.d/ . Весь пулл кон­фи­гов расо­пло­жен в дикер­то­рии /etc/php-fpm.d/ . Что­бы это рабо­та­ло, вы долж­ны доба­вить сле­ду­ю­щую стро­ку в php-fpm.conf :

Глобальная конфигурация PHP-FPM

Настрой­ки emergency_restart_threshold , emergency_restart_interval и process_control_timeout по умол­ча­нию выклю­че­ны, но я счи­таю что их сто­ит влю­чить, напри­мер, со сле­ду­ю­щи­ми значениями:

Что это зна­чит? Если 10 дочер­них про­цес­сов PHP-FPM завер­шат­ся с помо­щью SIGSEGV или SIGBUS в тече­нии 1 мину­ты, то PHP-FPM пере­за­гру­зит­ся авто­ма­ти­че­ски. А так­же дочер­ним про­цес­сам уста­нов­лен лимит вре­ме­ни реак­ции в 10 секунд на сиг­нал от мастера.

Конфигурация пулов PHP-FPM

В PHP-FPM воз­мож­но исполь­зо­вать отдень­ные пулы для каж­до­го сай­та и точ­но рас­пре­де­лять ресур­сы, а так­же исполь­зо­вать раз­ных поль­зо­ва­те­лей и раз­ные груп­пы для каж­до­го пула. При­ве­дем при­ме­ры кон­фи­гу­ра­ци трех раз­лич­нх сай­тов (или фак­ти­че­ски три части одно­го сайта):

/etc/php-fpm.d/site.conf
/etc/php-fpm.d/blog.conf
/etc/php-fpm.d/forums.conf

При­ме­ры кон­фи­гу­ра­ции каж­до­го пула:
/etc/php-fpm.d/site.conf

/etc/php-fpm.d/blog.conf

/etc/php-fpm.d/forums.conf

Это про­сто при­ме­ры как настро­ить несколь­ко раз­лич­ных пулов.

Конфигурация менеджера процессов (Pool Process Manager) PHP-FPM

Луч­ший спо­соб исполь­зо­вать мене­джер про­цес­сов PHP-FPM — это дона­ми­че­ское управ­ле­ние про­цес­са­ми, поэто­му PHP-FPM запус­ка­ет про­цес­сы толь­ко при необ­хо­ди­мо­сти. Это почти такой же под­ход как в Nginx с пара­мет­ра­ми worker_processes и worker_connections . Таким обра­зом боль­шие зна­че­ния не обес­пе­чи­ва­ют хоро­ше­го резуль­та­та. Каж­дый про­цесс ест опре­делн­ное коли­че­ство памя­ти и, конеч­но, если у сай­та очень боль­шой тра­фик и мно­го опе­ра­тив­ной памя­ти на сер­ве­ре, то высо­кие зна­че­ния — это пра­виль­ный выбор. Но такие сер­ве­ры как VPS обыч­но име­ют огра­ни­чен­ное коли­че­ство памя­ти: 256 Мб, 512 Мб, 1024 Мб. Тако­го неболь­шо­го объ­е­ма ОЗУ доста­точ­но даже для очень боль­шо­го тра­фи­ка (даже десят­ки запро­сов в секун­ду), если эту память исполь­зо­вать с умом.

Про­ве­рим сколь­ко про­цес­сов PHP-FPM поз­во­лит лег­ко справ­лять­ся сер­ве­ру с нагруз­кой. Сна­ча­ла запу­стим Nginx и PHP-FPM и загру­зим несколь­ко стра­ниц PHP , жела­тель­но самые тяже­лые. Затем про­ве­рим сколь­ко исполь­зу­ет памя­ти про­цесс PHP-FPM — в Linux мож­но вос­поль­зо­вать­ся ути­ли­та­ми top или htop . Пред­по­ло­жим что наш сер­вер име­ет 512 Мб опе­ра­тив­ной памя­ти и 220 Мб может быть исполь­зо­ван­но PHP-FPM , каж­дый про­цесс исполь­зу­ет 24 Мб опе­ра­тич­ной памя­ти (неко­то­рые CMS с пла­ги­на­ми могут лег­ко кушать 20-40 Мб на один запрос или даже боль­ше). Затем про­сто вычис­лим знач­ние max_children для сервера:

При­ем­ле­мым знач­ни­ем pm.max_children будет 9. Это знач­ние осно­ван­но на сред­нем зна­че­нии и воз­мож­но далее его необ­хо­ди­мо будет изме­нить, когда вы заме­ти­те дли­тель­ное вре­мя исполь­зо­ва­ния памя­ти про­цес­сом. После быст­ро­го тести­ро­ва­ния неслож­но выбрать знач­ния pm.start_servers value , pm.min_spare_servers и pm.max_spare_servers .

Окон­ча­тель­ная кон­фи­гу­ра­ция наше­го при­ме­ра может выгля­деть сле­ду­ю­щим образом:

Мак­си­ма­ло­ное коли­че­ство запро­сов на про­цесс по умол­ча­нию не огра­ни­че­но, но хоро­шо бы уста­но­вить какое-нибудь неболь­шое зна­че­ние, напри­мер 200, и избе­жать про­блем с памя­тью. Тако­го вида настро­ка может обра­ба­ры­вать боль­шое коли­че­ство запро­сов, даже если зна­че­ние пара­мет­ра невелико.

Подроб­ный раз­бор пара­мет­ров кон­фи­гу­ра­ци­он­ных файлов:

Источник

Как ускорить приложение за счёт PHP-FPM (няшим FPM conf)

Сегодня хочу поговорить о том, как ускорить приложение через конфигурирование PHP-FPM.

Сейчас самый популярный (из тех с которыми я сталкивался) стек на котором поднимается PHP приложение это веб сервер nginx и процесс-менеджер php-fpm.

Я хочу поднять простое приложение с Laravel проектом, которое устанавливается со всеми параметрами по умолчанию. Попробуем это приложение нагрузить пользователями с помощью простого Javascript скрипта и посмотрим как ему удастся справиться с нагрузкой и как мы можем повысить обрабатываемую нагрузку только конфигурированием php-fpm. В конце статьи можно будет найти ссылку на GitHub и попробовать своими руками.

Для начала посмотрим на стандартную конфигурацию php-fpm и попытаемся понять где могут быть проблемы в производительности с коробки.

Итак, у меня есть простое приложение на PHP с NGINX и PHP-FPM предустановленными в стандартных конфигурациях и маршрут Laravel.

Маршрут симулирует нагрузку через команду засыпания на одну секунду и возвращает простой json ответ.

Так же у меня есть Javascript файл который производит запрос на наш роут. Запускать его мы будем с помощью нагрузочной утилиты k6.

Для того чтобы провести нагрузочное тестирование давайте запустим утилиту k6 с пятью VU (virtual users)

k6 run —vus 5 —duration 30s script.js

Как видим в строке http_req_duration avg (среднее по всем показателям значение) равно 1.77 сек. Это сама нагрузка 1 секунда + время прохода запроса по сети и работа фреймворка.

Давайте проведём еще один такой же тест но на 10и пользователях

k6 run —vus 10 —duration 30s script.js

Как видим время возросло почти в два раза.

Давайте проведём еще один тест и будем разбираться в чём же дело.

На этот раз попробуем нагрузить сразу 50ью пользователями наше приложение.

k6 run —vus 50 —duration 30s script.js

Как видим результат стал совсем грустным. В среднем клиенту приходится ждать ответа от сервера 15.48 секунд. Давайте разбираться в чём дело.

Для начала давайте узнаем какая сейчас конфигурация php-fpm. Сделать это можно с помощью команды php-fpm -tt

Эта команда выведет все параметры php-fpm, самые важные параметры я обвел рамкой.

Самый важный параметр — это pm.max_children он равен сейчас 5. Этот параметр сообщает нашему php-fpm сколько он может максимально запустить дочерних процессов (обработчиков) запросов. Иными словами сколько параллельно процессов будет обрабатывать входящую нагрузку.

Для лучшей наглядности я нарисовал небольшую схему.

Когда в наше приложение одномоментно приходит 50 клиентов они сначала обращаются в наш NGINX, он является просто прокси сервером и пробрасывает запросы сквозь себя на PHP-FPM (за исключением запросов за статическими ресурсами/файлами) и дальше PHP-FPM пытается обработать все запросы с помощью своих процессов (воркеров). Если же ситуация как у нас, когда PHP-FPM располагает только пятью воркерами, то первые 5 клиентов обрабатываются, а остальные 45 становятся в очередь и ждут, когда первые 5 обработаются. Как только первые 5 отработали, следующие 5 зашли на их место и оставшиеся 40 ждут в очереди.

На этом этапе появляется две проблемы. Первая — мы заставляем таким образом ждать клиентов ответа, вторая — если время ожидания будет выше стандартного для NGINX в параметре fastcgi_read_timeout (стандартное 30 секунд) то мы можем получить 504 ошибку от NGINX. Вторую проблему мы можем исправить увеличив время ожидания, но это не спасет нас от первой проблемы.

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

Давайте вернёмся к нашим конфигурационным параметрам и постараемся сделать правильную настройку.

Итак, нас интересуют следующие параметры:

pm = dynamic — php-fpm сам контролирует количество запущенных воркеров, при указанном параметре dynamic php-fpm будет в зависимости от нагрузки добавлять или удалять воркеры. Так же в этом параметре может быть значение static в таком случае количество воркеров будет статическим.

pm.max_children — максимальное количество процессов единовременно работающих. Часто это значение ставится в количестве 4 * на количество CPU. Для того чтобы узнать количество CPU можно воспользоваться командой lscpu.

Более правильно будет еще проверить количество свободной памяти, можно сделать это командой free -hl

Обязательно нужно понимать сколько памяти занимает один воркер.

Это можно сделать с помощью команды htop и посмотреть среднее количество памяти которое занимают воркеры php-fpm

pm.min_spare_servers — минимальное количество процессов в состоянии ожидания. Это количество нужно как резервное в случае внезапного появления нового количества клиентов. Чтобы клиенты не ждали пока новые процессы создадутся резервные процессы подхватят внезапную нагрузку. Значение обычно ставится в 2 * на количество CPU.

pm.max_spare_servers — максимальное количество процессов в состоянии ожидания. В случае если нет нагрузки на приложение php-fpm удалит лишние процессы с целью сохранить оперативную память.

Хорошо, давайте сконфигурируем наш PHP-FPM.

Для начала найдем где находится файл конфигурации с помощью команды

И повторим нагрузочное тестирование с 50ью пользователями.

Как видите результат нагрузки средний 1.6 секунд. Примерно как и был в первом тесте, с пятью пользователями.

Так же еще можно посмотреть как отрабатывает php-fpm при установке pm стратегии в dynamic. Если вы запустите htop, то увидите стартовое количество воркеров

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

и после окончания теста снизится до начального.

Источник

Читайте также:  Java error script discord
Оцените статью