Nginx увеличить память php

Обновлено: 06.07.2024

pm = dynamic – количество дочерних процессов устанавливается динамически, основываясь на следующих директивах: pm.max_children , pm.start_servers , pm.min_spare_servers , pm.max_spare_servers .

pm = ondemand – процессы плодятся по требованию (при необходимости, в отличие от динамического варианта, где pm.start_servers запускаются при запуске сервиса).

pm = static – количество дочерних процессов фиксировано директивой pm.max_children .

…вы можете посмотреть полный список директив php-fpm.conf для получения дополнительной информации.

Менеджер процессов (process manager) PHP-FPM-а схож с CPUFreq Governor

Это может показаться немного не по теме, но я надеюсь связать его с нашей оптимизацией PHP-FPM. Да, все мы когда-то натыкались на проблемы с производительностью процессора, будь то ноутбук, виртуальная машина или выделенный сервер. Помните масштабирование частоты процессора? (CPUFreq governor) Эти параметры, доступные на *nix и Windows, могут повысить производительность и отзывчивость системы путем изменения настройки CPU governor с ondemand на performance . Сейчас давайте сравним описания и поищем сходства:

Governor = ondemand – Динамически увеличивает/уменьшает тактовую частоту процессора в зависимости от загруженности системы. Выводит до максимальной частоты, а потом уменьшает по мере увеличения времени простоя.

Governor = conservative – Похож на ondemand, но более экономный (предпочтение отдаётся меньшим тактовым частотам). Частота растёт более плавно.

Governor = performance – Поддерживает процессор(ы) на максимальной тактовой частоте.

… для дополнительной информации см. полный список настроек CPUFreq governor.

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

Настройка performance в CPU governor – это довольно безопасный прирост производительности, потому что это почти полностью зависит от предела процессора вашего сервера. Но есть несколько побочных эффектов (при постоянном удерживании частоты вашего процессора на 100%) – такие, как нагрев, время автономной работы (ноутбук) и другие. Однако это действительно самый быстрый параметр для вашего процессора.

Использование pm = static для максимальной производительности вашего сервера

Настройка pm = static в PHP-FPM сильно зависит от того, сколько свободной памяти на сервере. В основном, если вы страдаете от нехватки памяти сервера, то pm ondemand или dynamic могут оказаться лучшими вариантами. С другой стороны, если у вас достаточно свободной памяти, вы можете избежать большей части накладных расходов менеджера процессов, установив pm static до максимальной емкости сервера. Другими словами, когда вы делаете расчёты, pm.static нужно установить на максимальное количество PHP-FPM процессов, которые могут выполняться без создания проблем доступности памяти или кеша; однако, не так высоко, чтобы перегрузить процессор(ы) и иметь кучу отложенных операций PHP-FPM-а.

Тут отображаются не все процессы, а только та часть, что вместилась в ваше терминальное окно. В нашем случае отсортированных по %CPU (потреблению процессора). Чтобы увидеть все 100 PHP-FPM процессов, вы можете использовать что-то вроде этого:

Когда использовать pm ondemand и dynamic

Используя режим dynamic , вы можете наткнуться на подобные ошибки:

Вы можете попытаться увеличить/изменить настройки и по-прежнему видеть ту же ошибку. Подобная ситуация описана в этом вопросе на Serverfault. В таком случае, pm.min была слишком низкой, а т. к. трафик сильно колеблется, режим dynamic достаточно сложно настроить правильно. Общий совет: используйте ondemand , как советуют в этом же вопросе. Однако что еще хуже, т. к. ondemand будет завершать процессы в простое вплоть до 0 когда мало трафика, то после вы получите настолько много накладных расходов, насколько скакнёт трафик. Если, конечно, вы не установите время ожидания чрезвычайно высоким. В этом случае вам просто нужно использовать pm = static + высокий pm.max_requests .

Заключение

Когда дело доходит до PHP-FPM, раз вы начали получать серьезный трафик, то режимы ondemand и dynamic могут ограничить пропускную способность из-за свойственного оверхеда. Исследуйте вашу систему и установите количество процессов в наибольшее, с которым справится ваш сервер. Начните с pm.max_children , установленным на основе максимального использования режимов dynamic или ondemand , а затем увеличивайте до точки, где память и процессор остаются не перегруженными. Вы заметите, что с pm = static , т. к. вы держите всё в памяти, всплески трафика со временем будут меньше влиять на всплески загрузки процессора, а показатели загрузки и средней загрузки станут более сглаженными. Средний размер вашего PHP-FPM-процесса будет зависеть от конкретного веб-сервера, требующего ручной настройки, вот почему автоматизированные режимы – dynamic и ondemand – являются более популярными рекомендациями. Надеюсь, это была полезная статья.

Стандартные библиотеки PHP умеют генерировать только целые случайные числа. Однако, возникают задачи где нужно не целое рандомное число с максимально…

Иногда при обработке с помощью PHP больших и не очень данных, можно словить досадную ошибку посреди выполнения скрипта: PHP Fatal…

Настройки потребления ресурсов в PHP скриптах можно установить в главном конфигурационном файле php.ini, а также в самих скриптах.

В файле php.ini за это отвечают директивы из раздела Resource Limits (ограничение потребления ресурсов).

Как увеличить память для PHP скриптов

Для этого в файле php.ini найдите и отредактируйте директиву:

Эта директива задаёт максимальное время в секундах, в течение которого скрипт должен полностью загрузиться. Если этого не происходит, парсер завершает работу скрипта. Этот механизм помогает предотвратить зависание сервера из-за плохо написанного скрипта. По умолчанию на загрузку даётся 30 секунд. Если PHP запущен из командной строки, это значение по умолчанию равно 0.

На максимальное время выполнения не влияют системные вызовы, потоковые операции и т.п.

При работе в безопасном режиме эту настройку нельзя изменить функцией ini_set(). Если значение все же нужно изменить, надо либо выключить безопасный режим, либо изменить значение прямо в php.ini.

Веб-серверы обычно имеют свои настройки тайм-аута, по истечении которого сами завершают выполнение скрипта PHP. В Apache есть директива Timeout, в IIS есть функция CGI timeout. В обоих случаях по умолчанию установлено 300 секунд. Точные значения можно узнать из документации к веб-серверу.

Функция для увеличения и ограничения времени выполнения PHP

Функция set_time_limit ограничивает время выполнения скрипта.

Она задает время в секундах, в течение которого скрипт должен завершить работу. Если скрипт не успевает, вызывается фатальная ошибка. По умолчанию дается 30 секунд, либо время, записанное в настройке max_execution_time в php.ini (если такая настройка установлена).

При вызове set_time_limit() перезапускает счетчик с нуля. Другими словами, если тайм-аут изначально был 30 секунд, и через 25 секунд после запуска скрипта будет вызвана функция set_time_limit(20), то скрипт будет работать максимум 45 секунд.

  • СЕКУНДЫ (максимальное время выполнения в секундах. Если задан ноль, время выполнения неограничено)

Возвращаемые значения: возвращает TRUE в случае успеха, иначе FALSE.

Внимание: эта функция не работает, если PHP работает в безопасном режиме. Обойти это ограничение можно только выключив безопасный режим или изменив значение настройки в php.ini.

Замечание: функция set_time_limit() и директива max_execution_time влияют на время выполнения только самого скрипта. Время, затраченное на различные действия вне скрипта, такие как системные вызовы функции system(), потоковые операции, запросы к базам данных и т.п. не включаются в расчет времени выполнения скрипта. Это не относится к системам Windows, где расчитывается абсолютное время выполнения.

Увеличение выделенной памяти для PHP скриптов

Директива в файле php.ini

задаёт максимальный объем памяти в байтах, который разрешается использовать скрипту. Это помогает предотвратить ситуацию, при которой плохо написанный скрипт съедает всю доступную память сервера. Для того, чтобы убрать ограничения, установите значение этой директивы в -1.

В версиях до PHP 5.2.1 для использования этой директивы, она должна была быть указана на этапе компиляции. Так, ваша строка конфигурации должна была включать: --enable-memory-limit. Эта опция компиляции была также необходима для использования функций memory_get_usage() и memory_get_peak_usage() до версии 5.2.1.

Если используется целое число, то значение измеряется байтами. Вы также можете использовать сокращённую запись.

Доступные опции: K (для килобайт), M (для мегабайт) и G (для гигабайт; доступна начиная с PHP 5.1.0); они регистронезависимы. Все остальное считается байтами. 1M равно одному мегабайту или 1048576 байтам. 1K равно одному килобайту или 1024 байтам. Эти сокращения вы можете использовать в php.ini и в функции ini_set(). Обратите внимание, что числовое значение приводится к типу integer; например, 0.5M интерпретируется как 0.

Увеличение времени парсинга данных из запроса.

Директива в файле php.ini

задаёт максимальное время в секундах, в течение которого скрипт должен разобрать все входные данные, переданные запросами вроде POST или GET. Это время измеряется от момента, когда PHP вызван на сервере до момента, когда скрипт начинает выполняться. Значение по умолчанию -1, что означает, что будет использоваться max_execution_time. Если установить равным 0, то ограничений по времени не будет.

При запуске в командной строке значение директивы установлено на -1 (неограниченно).

Увеличение глубины вложенности входных переменных

Директива в файле php.ini

задаёт максимальную глубину вложенности входных переменных (то есть $_GET, $_POST.). По умолчанию данная директива закомментирована.

Ограничение на количество входных переменных

Директива в файле php.ini

определяет, входных переменных может быть принято в одном запросе (ограничение накладывается на каждую из глобальных переменных $_GET, $_POST и $_COOKIE отдельно). Использование этой директивы снижает вероятность сбоев в случае атак с использованием хеш-коллизий. Если входных переменных больше, чем задано директивой, выбрасывается предупреждение E_WARNING, а все последующие переменные в запросе игнорируются. По умолчанию данная директива закомментирована.

Внимание: после внесения изменений в файл php.ini необходимо перезагрузить веб-сервер, чтобы изменения вступили в силу.

Проверка использование ресурсов

Функция getrusage получает информацию об использовании текущего ресурса.

Возвращаемые значения: возвращает ассоциативный массив, содержащий данные возвращённые из системного вызова. Имена элементов соответствуют документированным именам полей.

Пример использования getrusage():


Увеличение разрешённого размера файлов для загрузки на сервер

Кроме описанных ограничений на потребление непосредственных ресурсов веб-сервера, также имеются ограничения, которые оказывают косвенное воздействие на ресурсы: например, загрузка слишком большого файла на сервер может потребовать большого количества ресурсов для его обработки, либо привести к переполнению дискового хранилища сервера. Поэтому существуют дополнительные лимиты, включённые в другие разделы конфигурационного файла помимо Resource Limits.

В частности, директива

устанавливает максимальный размер закачиваемого файла.

Если используется целое число, значение измеряется байтами. Вы также можете использовать сокращённую запись, которая описана чуть выше.

Максимально допустимый размер данных, отправляемых методом POST

Методом пост могут отправляться как текстовые данные (например, при отправке комментария на сайт), так и файлы. Если вы увеличили значение upload_max_filesize чтобы иметь возможность загружать файлы большего размера на сайт, то также нужно увеличить и значение директивы:

Замечание: PHP разрешает сокращения значений байт, включая K (кило), M (мега) и G (гига). PHP автоматически преобразует все эти сокращения. Будьте осторожны с превышением диапазона 32-битных целых значений (если вы используете 32-битную версию), так как это приведёт к ошибке вашего скрипта.

Для полного снятия лимитов значение можно установить на 0.

Значение этой настройки игнорируется, если чтение данных POST отключено с помощью enable_post_data_reading.

Увеличение количества файлов, выгружаемых на сайт за один раз

устанавливает максимально разрешённое количество одновременно закачиваемых файлов. Начиная с PHP 5.3.4, пустые поля загрузки не рассматриваются этим ограничением.

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

Сервер: облачный 16 ядер х 2,66 ГГЦ / 512 RAM / 10Gb HDD.

Показания скрипта PhpSysInfo.

Результат исполнения команды free совпадает с показаниями PhpSysInfo.

Сервер — Debian 6, установлены nginx и php5-fpm с php-apc и memcached. Больше ничего там не крутится, даже почта — через ssmtp.

Вопрос: это нормально? Что делать? Куда копать? Как уменьшить потребление памяти?

А для чего Вам свободная память? Жалко что ли? Поделится если что, не волнуйтесь. У меня на 190 метрах памяти все забил, и ниче, и с мускулом делится и остальные не страдают. Волноваться стоит не когда память забита и все работает, а когда что-то не работает _потому что_ память забита. Хм. Вы правы, я уже думал об этом. Тем более, что и с бОльшими настройками все летало идеально и никаких проблем не было. Но отсутствие запаса по ОЗУ разве не критично для сервера? Критично когда программы «жадничают», или когда есть программы для которых критично отсутствие памяти (mongo), в остальном это не всегда критично, большинство программ с радостью подвинутся при первой нужде, особенно когда они резервируют память «просто так, на всякий случай». Спасибо большое. Ну а кому верить — команде free или показаниям Вебмина? Может быть, врут оба из-за того, что сервер — «облачный»? 50-60 мегабайт ОЗУ по запасу — приемлемо для того, чтобы быть спокойным? Вот тут уже не скажу ничего =) Точными цифрами не владею. Скажу только то что у меня виртуал со 190 озу. Тоже стоит нгинкс + фпм и мускул. Вся память полностью занята, в своп не лезет, значит всем все хватает. Да и тормозов не обнаруживается… Хотя и нагрузки нет =) Не сочтите за назойливость :) Я Вам уже жутко благодарен, но «полностью забиты» — это совсем полностью или, как и в моем случае, процентов 10 остается свободной памяти? piccy.info/view3/1262143/7bee40ab8b9986fc2df4ea030811426f/
Я ошибся, у меня 160 =) Забито «под чистую», ни капельки не оставило

free memory = wasted memory :D

Пока не начало тормозить или свопиться, заранее беспокоиться не о чем.

Solaris, например, вообще бы забрала всю RAM под дисковый кэш ZFS. Вернув при нужде, по первому требованию, когда кому-то понадобится.

free memory = wasted memory

Отличная фраза. Распечатаю и повешу над кроватью :) Спасибо.

Приду домой, посмотрю в книге, кто автор :) Если мне не изменяет мой склероз, то я когда-то давно, когда был молодой и худой, году в 1997, прочел эту фразу у Helen Custer в «Inside Windows NT». Но она там кого-то цитировала. прошу прощения, обещал и прообещался :) беглым взглядом цитату не нашел, а всю книгу внимательно перечитывать некогда. Могу предположить, что каждый воркер имеет в себе весь php-apc кеш, поэтому кушается столько памяти.
Единственная проблема, которая может быть — php-fpm memory leak, но если после рестарта php-fpm он кушает примерно столько же памяти, сколько и до рестарта, значит утечек скорее всего нет
Ну и как вам уже сказали, волноваться надо, когда используется своп

Разобрался, в чем было дело: слишком сильно был раздут кэш при малом количестве рабочих процессов nginx и php-fpm, плюс была включена функция масштабирования нагрузки в свойствах сервера. Масштабирование отключил, количество рабочих процессов nginx и php-fpm значительно увеличил, кэш незначительно уменьшил — память освободилась до 150-200 мегабайт в зависимости от нагрузки, из них около 100 мегабайт кэша.

Как правило, настроенный должным образом сервер Nginx на Linux, может обрабатывать 500,000 — 600,000 запросов в секунду. Но этот показатель можно весьма ощутимо увеличить. Хотел бы обратить внимание на тот факт, что настройки описанные ниже, применялись в тестовой среде и, возможно, для ваших боевых серверов они не подойдут.

На всякий пожарный, создадим бэкап исходного конфига.

А теперь можно и похимичить!

Начнём с директивы worker_processes. Если Nginx выполняет работу нагружающую процессор (например SSL или gzipping), то оптимально установить эту директиву в значение, равное количеству ядер процессора. Выигрыш при большем значении вы получите только в случае обработки очень большого количества статики.

Также, директива worker_processes, умноженная на worker_connections из секции event, даст максимально возможное количество клиентов.

Последняя пролетарская директива, которую я хочу затронуть — это worker_rlimit_nofile. Данная директива указывает сколько файловых дескрипторов будет использовать Nginx. На каждое соединение надо выделять по два дексриптора, даже для статических файлов (картинки/JS/CSS): один для соединения с клиентом, а второй — для открытия статического файла. Таким образом, значение worker_rlimit_nofile должно быть равным удвоенному значению Max Clients. В системе это значение можно установить из командной строки ulimit -n 200000 или используя /etc/security/limits.conf.

Теперь разберёмся с логированием. Во-первых, оставим логирование только критических ошибок.

Если вы совсем бесстрашны и хотите отключить логирование ошибок целиком, то помните, что error_log off вам не поможет. Вы просто получите весь лог в файле off. Для отключения логирования ошибок надо делать так:

А вот логи доступа не так страшно отключить полностью.

Или, хотя бы, включить буфер чтения / записи.

Для обработки подключений Nginx поддерживает ряд методов. Наиболее эффективным для Linuxявляется метод epoll.

Для того, чтобы Nginx пытался принять максимальное количество подключений, необходимо включить директиву multi_accept. Однако при слишком маленьком значении worker_connections, их лимит может быть очень быстро исчерпан.

Конечно же, нам не обойтись без кеширования информации о:

  • дескрипторах недавно открытых файлов: их размера и даты модификации;
  • существовании директорий;
  • ошибках при поиске файлов: отсутствие самого файла, отсутствие прав на чтение и т.д.

Советую не копировать значения директив кеширования, а поиграть с ними, подобрав оптимальные для вашего окружения.

Директива sendfile активирует копирование данных между файловыми дескрипторами средствами ядра, что намного эффективнее связки read() + write(), которая требует обмена данными с пользовательским пространством.

Для keep-alive подключений можно выключить буферизацию (алгоритм Нейгла). Это будет полезно при частом запросе маленьких объёмов данных в режиме реального времени, без получения немедленного ответа, когда важна своевременная доставка данных. Классический пример — события наведения мышкой.

Стоит обратить внимание на ещё две директивы для keep-alive подключений. Их назначение выглядит очевидным.

Чтобы высвободить дополнительную память, выделенную под сокеты, включите директиву reset_timedout_connection. Она разрешит серверу закрывать подключение тех клиентов, которые перестали отвечать.

Ещё можно существенно уменьшить тайм-ауты для директив client_body_timeout и send_timeout(дефолтное значение обеих — 60 секунд). Первая — ограничивает время на чтение тела запроса от клиента. Вторая — время ответа клиенту. Таким образом, если клиент не начнёт читать данные в указанный промежуток времени, то Nginx закроет подключение.

И, конечно же, сжатие данных. Плюс — единственный и очевидный: уменьшение размера пересылаемого трафика. Минус — единственный и очевидный: не работает для MSIE 6 и ниже. Отключить сжатие для этих браузеров можно директивой gzip_disable, указав в качестве значения специальную маску “msie6”, которая соответствует регулярному выражению “MSIE 5\.”, но работает быстрее (спасибо hell0w0rd за комментарий).

Пожалуй, это всё, о чём я хотел рассказать. Скажу лишь ещё раз, что не стоит копировать приведенные настройки один в один. Я советую применять их по одной, каждый раз запуская какую-нибудь утилиту для нагрузочного тестирования (например, Tsung). Это весьма важно для понимания, какие настройки реально ускоряют ваш веб-сервер. Методичность в тестировании сэкономит вам уйму времени.

P.S. Все настройки одним куском для бесстрашных лентяев

В данной статье я приведу примеры оптимизации сервера приложений под linux. Важной целью для улучшения производительности является правка файла настроек linux. Нас интересует настройки стека tcp/ip. Файл находится по пути /etc/sysctl.conf.

Замените содержимое файла на

Далее в файлах upstream php-fpm (/etc/php-fpm.d/*) предлагаются на выбор статический и динамический режимы работы. Для экономии памяти лучше выбирать динамический. Также нужно рассчитать количество процессов php-fpm на основе количества оперативной памяти Вашего сервера. Делается это по формуле

Favorite

Добавить в избранное

Главное меню » Операционная система Linux » Настройка PHP-FPM для повышения производительности + Low Memory

(1 оценок, среднее: 5,00 из 5)

Настройка PHP-FPM для повышения производительности + Low Memory

P HP-FPM имеет конфигурацию по умолчанию, которая использует больше памяти, чем это необходимо. Она имеет запасные PHP-FPM процессы, готовые запускаться, занимая память в случае, если есть PHP код в обработки. Хотя это и не проблема, если у вас есть тонны оперативной памяти, это может быть проблемой для низкой VPS RAM и если вы используете агрессивное кэширование страниц, то это память используется без необходимости, которая может быть использована для MariaDB (MySQL) или для других важных процессов. Это руководство объясняет, как настроить конфигурацию Nginx с PHP-FPM работающем на PHP 7.0, чтобы использовать как можно меньше оперативной памяти, как это возможно.

Настройка PHP-FPM для повышения производительности + Low Memory

Откройте файл конфигурации PHP-FPM для PHP 7.0.

Настройте следующие значения, как показано ниже, обратите внимание на ; перед pm.start_servers , pm.min_spare_servers и pm.max_spare_servers .

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

pm.max_children это максимальное количество дочерних процессов, которые будут разрешены, 50 является достаточно либеральным, но если вы видите в своем архиве журналов что количество дочерних процессов превысило максимальное значение, то необходимо увеличить это значение

pm.process_idle_timeout убивает дочерние процессы после того, как они бездействовали в течение 10 секунд

pm.max_requests устанавливает максимальное количество запросов PHP для каждого дочернего процесса

Проверьте правильность вашего синтаксиса конфигурации PHP-FPM

Вы должны увидеть, что конфигурация действует

Теперь вы можете перезапустить php7.0-FPM

Вы можете увидеть, что объем оперативной памяти используется значительно меньше.

Если вы нашли ошибку, пожалуйста, выделите фрагмент текста и нажмите Ctrl+Enter.

Читайте также: