Ускорение и оптимизация PHP-сайта. Какие технологии стоит выбирать при настройке сервера под PHP. Оптимизация php fpm
Настройка и highload-тюнинг php-fpm | Evil Inside
Попробуем определить каким образом можно повысить производительность сервера приложений на базе php-fpm, а также сформировать чек-лист для проверки конфигурации fpm процесса.
Прежде всего стоит определить расположение файла-конфигурации пула. Если вы устанавливали php-fpm из системного репозитория, то конфигурация пула www будет расположена примерно тут /etc/php5/fpm/pool.d/www.conf. В случае если используется свой билд или другая ОС (не debian) следует поискать расположение файла в документации, или указывать его вручную. Попробуем рассмотреть конфигурацию подробней.
Переходим на UNIX-сокеты
Наверное первое, на что следует обратить внимание, это то как проходят данные от веб-сервера к вашим php процессам. Это отражено в директиве listen:
В случае если установлен адрес:порт, то данные идут через стек TCP, и это наверное не очень хорошо. Если же там путь к сокету, например:
то данные идут через unix-сокет, и можно пропустить этот раздел.
Почему все таки стоит перейти на unix-сокет? UDS (unix domain socket), в отличии от комуникции через стек TCP, имеют значительные преимущества:
- не требуют переключение контекста, UDS используют netisr)
- датаграмма UDS записываться напрямую в сокет назначения
- отправка дейтаграммы UDS требует меньше операций (нет контрольных сумм, нет TCP-заголвоков, не производиться маршрутизация)
И вот некоторые тесты:
TCP средняя задержка: 6 us UDS средняя задержка: 2 us PIPE средняя задержка: 2 us TCP средняя пропускная способность: 253702 msg/s UDS средняя пропускная способность: 1733874 msg/s PIPE средняя пропускная способность: 1682796 msg/sТаким образом, у UDS задержка на ~66% меньше и пропускная способность в 7 раз больше TCP. Поэтому, скорей всего стоит перейти на UDS. В моем случае сокет будет расположен по адресу /var/run/php5-fpm.sock.
; закоментируем это - listen = 127.0.0.1:9000 listen = /var/run/php5-fpm.sockПроверяем выбранный механизм обработки событий
Для работы с эффективной работы с I/O (вводом-выводом, дескрипторами файлов/устройств/сокетов) стоит проверить правильно ли указана настройка events.mechanism. В случае если php-fpm установлен из системного репозитория, скорей всего там все в порядке — он либо не указан (устанавливаться автоматически), либо указан корректно.
Его значение зависит от ОС, для чего есть подсказка в документации:
; - epoll (linux >= 2.5.44) ; - kqueue (FreeBSD >= 4.1, OpenBSD >= 2.9, NetBSD >= 2.0) ; - /dev/poll (Solaris >= 7) ; - port (Solaris >= 10)К примеру если мы работаем на современном linux-дистрибутивe нам необходим epool:
Выбор типа пула — dynamic / static / ondemand
Также, стоит обратить внимание на настройки менеджер процессов (pm). По сути это главный процесс (master process), который будет управлять всеми дочерними (которые выполняют код приложения) по определенной логике, которая собственно и описана в файле конфигурации.
Всего доступно 3 схемы управления процессами:
Наиболее простой — это static. Схема его работы заключается в следующем: запустить фиксированное количество дочерних процессов, и поддерживать их в рабочем состоянии. Данная схема работы не очень эффективна, так как количество запросов и их нагрузка может меняться время от времени, а количество дочерних процессов нет — они всегда занимают определенный объем ОЗУ и не могут обрабатывают пиковые нагрузки в порядке очереди.
dynamic пул позволят решить эту проблему, он регулирует количество дочерних процессов исходя из значений конфигурационного файла, изменяя их в большую или меньшую сторону, в зависимости от нагрузки. Данный пул больше всего подходит для сервера приложений, в котором необходима быстрая реакция на запрос, работа с пиковой нагрузкой, требуется экономия ресурсов (за счет уменьшения дочерних процессов при простое).
Утечки памяти и OOM killer
Следует обратить внимание на качество приложений которые будут выполняться дочерними процессами. Если качество приложения не очень высоко, или используются множество сторонних библиотек, то необходимо подумать о возможных утечках памяти, и установить значения таким переменным:
- pm.max_requests
- request_terminate_timeout
pm.max_requests это максимальное количество запросов, которое обработает дочерний процесс, прежде чем будет уничтожен. Принудительное уничтожение процесса позволяет избежать ситуации в которой память дочернего процесса “разбухнет” по причине утечек (т.к процесс продолжает работу после от запроса к запросу). С другой стороны, слишком маленькое значение приведет к частым перезапускам, что приведет к потерям в производительности. Стоит начать с значения в 1000, и далее уменьшить или увеличить это значение.
request_terminate_timeout устанавливает максимальное время выполнения дочернего процесса, прежде чем он будет уничтожен. Это позволяет избегать долгих запросов, если по какой-либо причине было изменено значение max_execution_time в настройках интерпретатора. Значение стоит установить исходя из логики обрабатываемых приложений, скажем 60s (1 минута).
Настройка dynamic пула
Для основного сервера приложения, ввиду явных преимуществ, часто выбирают dynamic пул. Его работа описана следующими настройками:
- pm.max_children — максимальное количество дочерних процессов
- pm.start_servers — количество процессов при старте
- pm.min_spare_servers — минимальное количество процессов, ожидающих соединения (запросов для обработки)
- pm.max_spare_servers — максимальное количество процессов, ожидающих соединения (запросов для обработки)
Для того чтобы корректно установить эти значения, необходимо учитывать:
- сколько памяти в среднем потребляет дочерний процесс
- объем доступного ОЗУ
Выяснить среднее значение памяти на один php-fpm процесс на уже работающем приложении можно с помощью планировщика:
Нам необходимо среднее значение в колонке RSS (размер резидентной памяти в килобайтах). В моем случае это ~20Мб. В случае, если нагрузки на приложения нет, можно использовать Apache Benchmark, для создания простейшей нагрузки на php-fpm.
Объем общей / доступной / используемой памяти можно посмотреть с помощью free:
# free -m total used free ... Memory: 4096 600 3496Далее, возьмем за основу формулу для расчета pm.max_children и проведем расчет на примере:
Total Max Processes = (Total Ram - (Used Ram + Buffer)) / (Memory per php process) Всего ОЗУ: 4Гб Используется ОЗУ: 1000Мб Буфер безопасности: 400Мб Память на один дочерний php-fpm процесс (в среднем): 30Мб Максимально возможное кол-во процессов = (4096 - (1000 + 400)) / 30 = 89 Четное количество: 89 округлили в меньшую сторону до 80Значение остальных директив можно установить исходя из ожидаемой нагрузки на приложение а также учесть чем еще занимается сервер кроме работы php-fpm (скажем СУБД также требует ресурсов). В случае наличия множества задач на сервере — стоит снизить к-во как начальных / максимальных процессов.
К примеру учтем что на сервере находиться 2 пула www1 и www2 (к примеру 2 веб-ресурса), тогда конфигурация каждого из них может выглядеть как:
pm.max_children = 40 ; 80 / 2 pm.start_servers = 15 pm.min_spare_servers = 15 pm.max_spare_servers = 25Читайте также
evilinside.ru
Советы по настройке и оптимизации Nginx и PHP-FPM : Black Box
От переводчика:Речь пойдет о тонкостях настройки связки Nginx + PHP-FPM в виде небольшого сборника советов. Перевод вольный. Ориентированно на пользователей Linux.
Советы по настройке и оптимизации Nginx
Совет №1 – Организация файлов конфигурации Nginx
Обычно файлы конфигурации Nginx хранятся в /etc/nginx.
Один из удобных способов организации файлов конфигурации в стиле Debian/Ubuntu Apache:
## Главный файл конфигурации
## Файлы конфигурации вируальных хостов (virtualhost) ## /etc/nginx/sites-available/ /etc/nginx/sites-enabled/
## Другие файлы конфигурации (если необходимы) ## /etc/nginx/conf.d/ |
Файлы виртуальных хостов разделены на две директории. Директория sites-available может содержать любые файлы: тестовые, старые конфиги, копии конфигов и прочие. А директорияsites-enabled содержит только реально работающие конфигурации, в действительности являющиеся только символическими ссылками на файлы в директории sites-available.
Не забудьте добавить следующие строки в файл nginx.conf:
## Загрузка файлов конфигарации виртуальных хостов ## include /etc/nginx/sites-enabled/*;
## Загрузка других конфигов из conf.d/ ## include /etc/nginx/conf.d/*; |
Совет №2 – Определить Nginx worker_processes и worker_connections
Настройки по умолчанию хороши, но их стоит немного оптимизировать: max_clients = worker_processes * worker_connections.
Базовые настройки Nginx могут обрабатывать сотни одновременных соединений:
worker_processes 1; worker_connections 1024; |
Обычно 1000 одновременных соединений на один сервер это хорошо, но порою другие части, например жесткий диск могут оказаться медленными и это приведет к тому, что Nginx будет заблокирован на операции ввода-вывода (I/O). Чтобы избежать блокировки используйте, например, следующие настройки: одни worker_process на ядро процессора:
Worker Processes
worker_processes = [число ядер процессора]; |
Чтобы определить сколько ядер имеет ваш процессор, введите:
$ cat /proc/cpuinfo | grep processor processor : 0 processor : 1 processor : 2 processor : 3 |
В данном случае у меня четыре ядра, поэтому окончательный парамерт worker_processesустанавливаем как 4:
Worker Connections
Лично я придерживаюсь 1024 соединений на один воркер, потому что у меня нет никаких оснований для повышения этого значения. Но если например 4096 соединений в секунду не хватает, то можно попробовать удвоить 2048 соединений на процесс.
Окончательные настройки выглядят седующим образом:
Совет №3 – Скрыть токены Nginx / Скрыть номер версии Nginx
Это хорошо из соображений безопасности – скрыть токены Nginx и скрыть номер версии Nginx, тем более если вы используете устаревшую версию Nginx. Это очень легко сделать – достаточно добавить в секцию http/server/location файла конфигурации следующую строку:
Совет №4 – Ограничение на размер передаваемых данных сервером Nginx
Если вы хотите разрешить пользователям загружать файлы, то вы должны увеличить размер сообщения. Это может быть сделано с помощью значения client_max_body_size, которое находится в секции http/server/location файла конфигурации. По умолчанию он равен 1 Мб, но его можно увеличить, например, до 20 Мб, а также увеличить размер буфера:
client_max_body_size 20m; client_body_buffer_size 128k; |
Если вы получаете сообщение об ошибке, то вы знаете, что client_max_body_size слишком мало:
“Request Entity Too Large” (413)
Совет №5 – Управление кешем для статических файлов
Кэш браузера сохранит ресурсы и пропускную способность вашего сервера. Это несложная настройка Nginx позволит выключить ведение логов (access log и not found log), и установить срок истечения заголовка в 360 дней.
location ~* \.(jpg|jpeg|gif|png|css|js|ico|xml)$ { access_log off; log_not_found off; expires 360d; } |
Если вы хотите более сложный заголовки или другие типы файлов, то вы можете настроить их отдельно.
Совет №6 – Проксируйте PHP запросы к PHP-FPM
Вы можете использовать по умолчанию стек tcp/ip или соединение через Unix-сокет. Также необходимо установить PHP-FPM слушать точно такой же ip:port или Unix-сокет. Вот очень простой пример конфигурации (вариант с Unix-сокетом закоментирован):
# Pass PHP scripts to PHP-FPM location ~* \.php$ { fastcgi_index index.php; fastcgi_pass 127.0.0.1:9000; #fastcgi_pass unix:/var/run/php-fpm/php-fpm.sock; include fastcgi_params; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_param SCRIPT_NAME $fastcgi_script_name; } |
Это дает возможность запуска PHP-FPM другим сервером.
Совет №7 – Предотвращение (запрет) доступа к скрытым файлам
Это очень распространено, когда корень сервера или другие публичные каталоги имеют скрытые файлы, которые начинаются с точки (.) И, как правило, они не предназначены для пользователей сайта. Публичный каталог может содержать файлы системы контроля версий: .git, .svn; файлы IDE: .idea; .htaccess файлы. Настройки запещают доступ к скрытым файлам и отключают ведение логов:
location ~ /\. { access_log off; log_not_found off; deny all; } |
Советы по настройке и оптимизации PHP-FPM
Совет №1 – Файлы конфигурации PHP-FPM
Обычно конфигурации PHP-FPM расположенны в файле /etc/php-fpm.conf и в каталоге/etc/php-fpm.d/. Весь пулл конфигов расопложен в дикертории /etc/php-fpm.d/. Чтобы это работало, вы должны добавить следующую строку в php-fpm.conf:
include=/etc/php-fpm.d/*.conf |
Совет №2 – Глобальная конфигурация PHP-FPM
Настройки emergency_restart_threshold, emergency_restart_interval и process_control_timeoutпо умолчанию выключены, но я считаю что их стоит влючить, например, со следующими значениями:
emergency_restart_threshold 10 emergency_restart_interval 1m process_control_timeout 10s |
Что это значит? Если 10 дочерних процессов PHP-FPM завршатся с помощью SIGSEGV илиSIGBUS, то PHP-FPM перезагрузится через 1 минуту. А также дочерним процессам установлен лимит времени реакции в 10 секунд на сигнал от мастера.
Совет №3 – Конфигурация пулов 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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | [site] listen = 127.0.0.1:9000 user = site group = site request_slowlog_timeout = 5s slowlog = /var/log/php-fpm/slowlog-site.log listen.allowed_clients = 127.0.0.1 pm = dynamic pm.max_children = 5 pm.start_servers = 3 pm.min_spare_servers = 2 pm.max_spare_servers = 4 pm.max_requests = 200 listen.backlog = -1 pm.status_path = /status request_terminate_timeout = 120s rlimit_files = 131072 rlimit_core = unlimited catch_workers_output = yes env[HOSTNAME] = $HOSTNAME env[TMP] = /tmp env[TMPDIR] = /tmp env[TEMP] = /tmp |
/etc/php-fpm.d/blog.conf
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | [blog] listen = 127.0.0.1:9001 user = blog group = blog request_slowlog_timeout = 5s slowlog = /var/log/php-fpm/slowlog-blog.log listen.allowed_clients = 127.0.0.1 pm = dynamic pm.max_children = 4 pm.start_servers = 2 pm.min_spare_servers = 1 pm.max_spare_servers = 3 pm.max_requests = 200 listen.backlog = -1 pm.status_path = /status request_terminate_timeout = 120s rlimit_files = 131072 rlimit_core = unlimited catch_workers_output = yes env[HOSTNAME] = $HOSTNAME env[TMP] = /tmp env[TMPDIR] = /tmp env[TEMP] = /tmp |
/etc/php-fpm.d/forums.conf
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | [forums] listen = 127.0.0.1:9002 user = forums group = forums request_slowlog_timeout = 5s slowlog = /var/log/php-fpm/slowlog-forums.log listen.allowed_clients = 127.0.0.1 pm = dynamic pm.max_children = 10 pm.start_servers = 3 pm.min_spare_servers = 2 pm.max_spare_servers = 4 pm.max_requests = 400 listen.backlog = -1 pm.status_path = /status request_terminate_timeout = 120s rlimit_files = 131072 rlimit_core = unlimited catch_workers_output = yes env[HOSTNAME] = $HOSTNAME env[TMP] = /tmp env[TMPDIR] = /tmp env[TEMP] = /tmp |
Это просто примеры как настроить несколько различных пулов.
Совет №4 – Конфигурация менеджера процессов (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 для сервера:
220 / 24 = 9.17
Приемлемым значнием pm.max_children будет 9. Это значние основанно на среднем значении и возможно далее его необходимо будет изменить, когда вы заметите длительное время использования памяти процессом. После быстрого тестирования несложно выбрать значния pm.start_servers value, pm.min_spare_servers и pm.max_spare_servers.
Окончательная конфигурация нашего примера может выглядеть следующим образом:
pm.max_children = 9 pm.start_servers = 3 pm.min_spare_servers = 2 pm.max_spare_servers = 4 pm.max_requests = 200 |
Максималоное количество запросов на процесс по умолчанию не ограничено, но хорошо бы установить какое-нибудь небольшое значение, например 200, и избежать проблем с памятью. Такого вида настрока может обрабарывать большое количество запросов, даже если значение параметра невелико.
У вас проблемы с натройкой Nginx или PHP-FPM или есть еще советы?
Не стесняйтеся писать замечания, вопросы и советы в комментариях.
http://pektop.net/2013/09/sovety-po-nastrojke-i-optimizacii-nginx-i-php-fpm/
blackbox.freshdesk.com
Настраиваем php-fpm · Блог Новикова Богдана
16.09.2016Попробуем определить каким образом можно повысить производительность сервера приложений на базе php-fpm, а также сформировать чек-лист для проверки конфигурации fpm процесса.
Прежде всего стоит определить расположение файла-конфигурации пула. Если вы устанавливали php-fpm из системного репозитория, то конфигурация пула www будет расположена примерно тут /etc/php5/fpm/pool.d/www.conf. В случае если используется свой билд или другая ОС (не debian) следует поискать расположение файла в документации, или указывать его вручную.
Попробуем рассмотреть конфигурацию подробней.
Переходим на UNIX-сокеты
Наверное первое, на что следует обратить внимание, это то как проходят данные от веб-сервера к вашим php процессам. Это отражено в директиве listen:
В случае если установлен адрес:порт, то данные идут через стек TCP, и это наверное не очень хорошо. Если же там путь к сокету, например:
listen = /var/run/php5-fpm.sockто данные идут через unix-сокет, и можно пропустить этот раздел.
Почему все таки стоит перейти на unix-сокет? UDS (unix domain socket), в отличии от комуникции через стек TCP, имеют значительные преимущества:
- не требуют переключение контекста, UDS используют netisr)
- датаграмма UDS записываться напрямую в сокет назначения
- отправка дейтаграммы UDS требует меньше операций (нет контрольных сумм, нет TCP-заголвоков, не производиться маршрутизация)
И вот некоторые тесты:
TCP средняя задержка: 6 us UDS средняя задержка: 2 us PIPE средняя задержка: 2 us TCP средняя пропускная способность: 253702 msg/s UDS средняя пропускная способность: 1733874 msg/s PIPE средняя пропускная способность: 1682796 msg/sТаким образом, у UDS задержка на ~66% меньше и пропускная способность в 7 раз больше TCP. Поэтому, скорей всего стоит перейти на UDS. В моем случае сокет будет расположен по адресу /var/run/php5-fpm.sock.
; закоментируем это - listen = 127.0.0.1:9000 listen = /var/run/php5-fpm.sockТакже следует убедиться что веб-сервер (или любой другой процесс, которому необходима коммуникация) имеет доступ на чтение/запись в ваш сокет. Для этого существуют настройки listen.grup и listen.mode Проще всего - запускать оба процесса от одного пользователя или группы, в нашем случае php-fpm и веб-сервер будет запущен с группой www-data:
listen.owner = www-data listen.group = www-data listen.mode = 0660Проверяем выбранный механизм обработки событий
Для работы с эффективной работы с I/O (вводом-выводом, дескрипторами файлов/устройств/сокетов) стоит проверить правильно ли указана настройка events.mechanism. В случае если php-fpm установлен из системного репозитория, скорей всего там все в порядке - он либо не указан (устанавливаться автоматически), либо указан корректно.
Его значение зависит от ОС, для чего есть подсказка в документации:
; - epoll (linux >= 2.5.44) ; - kqueue (FreeBSD >= 4.1, OpenBSD >= 2.9, NetBSD >= 2.0) ; - /dev/poll (Solaris >= 7) ; - port (Solaris >= 10)К примеру если мы работаем на современном linux-дистрибутивe нам необходим epool:
Выбор типа пула - dynamic / static / ondemand
Также, стоит обратить внимание на настройки менеджер процессов (pm). По сути это главный процесс (master process), который будет управлять всеми дочерними (которые выполняют код приложения) по определенной логике, которая собственно и описана в файле конфигурации.
Всего доступно 3 схемы управления процессами:
Наиболее простой - это static. Схема его работы заключается в следующем: запустить фиксированное количество дочерних процессов, и поддерживать их в рабочем состоянии. Данная схема работы не очень эффективна, так как количество запросов и их нагрузка может меняться время от времени, а количество дочерних процессов нет - они всегда занимают определенный объем ОЗУ и не могут обрабатывают пиковые нагрузки в порядке очереди.
dynamic пул позволят решить эту проблему, он регулирует количество дочерних процессов исходя из значений конфигурационного файла, изменяя их в большую или меньшую сторону, в зависимости от нагрузки. Данный пул больше всего подходит для сервера приложений, в котором необходима быстрая реакция на запрос, работа с пиковой нагрузкой, требуется экономия ресурсов (за счет уменьшения дочерних процессов при простое).
ondemand пул очень похож на static, но он не запускает дочерних процессов при старте главного процесса. Только когда придет первый запрос - будет создан первый дочерний процесс, и по истечении определенного времени ожидания (указанного в конфигурации) он будет уничтожен. Потому он актуален для серверов с ограниченными ресурсами, или той логики которая не требует быстрой реакции.
Утечки памяти и OOM killer
Следует обратить внимание на качество приложений которые будут выполняться дочерними процессами. Если качество приложения не очень высоко, или используются множество сторонних библиотек, то необходимо подумать о возможных утечках памяти, и установить значения таким переменным:
- pm.max_requests
- request_terminate_timeout
pm.max_requests это максимальное количество запросов, которое обработает дочерний процесс, прежде чем будет уничтожен. Принудительное уничтожение процесса позволяет избежать ситуации в которой память дочернего процесса “разбухнет” по причине утечек (т.к процесс продолжает работу после от запроса к запросу). С другой стороны, слишком маленькое значение приведет к частым перезапускам, что приведет к потерям в производительности. Стоит начать с значения в 1000, и далее уменьшить или увеличить это значение.
request_terminate_timeout устанавливает максимальное время выполнения дочернего процесса, прежде чем он будет уничтожен. Это позволяет избегать долгих запросов, если по какой-либо причине было изменено значение max_execution_time в настройках интерпретатора. Значение стоит установить исходя из логики обрабатываемых приложений, скажем 60s (1 минута).
Настройка dynamic пула
Для основного сервера приложения, ввиду явных преимуществ, часто выбирают dynamic пул. Его работа описана следующими настройками:
- pm.max_children - максимальное количество дочерних процессов
- pm.start_servers - количество процессов при старте
- pm.min_spare_servers - минимальное количество процессов, ожидающих соединения (запросов для обработки)
- pm.max_spare_servers - максимальное количество процессов, ожидающих соединения (запросов для обработки)
Для того чтобы корректно установить эти значения, необходимо учитывать:
- сколько памяти в среднем потребляет дочерний процесс
- объем доступного ОЗУ
Выяснить среднее значение памяти на один php-fpm процесс на уже работающем приложении можно с помощью планировщика:
# ps -ylC php-fpm --sort:rss S UID PID PPID C PRI NI RSS SZ WCHAN TTY TIME CMD S 0 1445 1 0 80 0 9552 42588 ep_pol ? 00:00:00 php5-fpmНам необходимо среднее значение в колонке RSS (размер резидентной памяти в килобайтах). В моем случае это ~20Мб. В случае, если нагрузки на приложения нет, можно использовать Apache Benchmark, для создания простейшей нагрузки на php-fpm.
Объем общей / доступной / используемой памяти можно посмотреть с помощью free:
# free -m total used free ... Memory: 4096 600 3496Далее, возьмем за основу формулу для расчета pm.max_children (источник), и проведем расчет на примере:
Total Max Processes = (Total Ram - (Used Ram + Buffer)) / (Memory per php process) Всего ОЗУ: 4Гб Используется ОЗУ: 1000Мб Буфер безопасности: 400Мб Память на один дочерний php-fpm процесс (в среднем): 30Мб Максимально возможное кол-во процессов = (4096 - (1000 + 400)) / 30 = 89 Четное количество: 89 округлили в меньшую сторону до 80Значение остальных директив можно установить исходя из ожидаемой нагрузки на приложение а также учесть чем еще занимается сервер кроме работы php-fpm (скажем СУБД также требует ресурсов). В случае наличия множества задач на сервере - стоит снизить к-во как начальных / максимальных процессов.
К примеру учтем что на сервере находиться 2 пула www1 и www2 (к примеру 2 веб-ресурса), тогда конфигурация каждого из них может выглядеть как:
pm.max_children = 40 ; 80 / 2 pm.start_servers = 15 pm.min_spare_servers = 15 pm.max_spare_servers = 25hcbogdan.com
Оптимизация веб-серверов приложений на основе nginx+php-fpm
; Start a new pool named 'www'.
; the variable $pool can we used in any directive and will be replaced by the
; pool name ('www' here)
[www0]
; Per pool prefix
; It only applies on the following directives:
; - 'slowlog'
; - 'listen' (unixsocket)
; - 'chroot'
; - 'chdir'
; - 'php_values'
; - 'php_admin_values'
; When not set, the global prefix (or /usr) applies instead.
; Note: This directive can also be relative to the global prefix.
; Default Value: none
;prefix = /path/to/pools/$pool
; The address on which to accept FastCGI requests.
; Valid syntaxes are:
; 'ip.add.re.ss:port' - to listen on a TCP socket to a specific address on
; a specific port;
; 'port' - to listen on a TCP socket to all addresses on a
; specific port;
; '/path/to/unix/socket' - to listen on a unix socket.
; Note: This value is mandatory.
listen = /var/run/php-fpm.sock
; Set listen(2) backlog. A value of '-1' means unlimited.
; Default Value: 128 (-1 on FreeBSD and OpenBSD)
listen.backlog = 65536
; List of ipv4 addresses of FastCGI clients which are allowed to connect.
; Equivalent to the FCGI_WEB_SERVER_ADDRS environment variable in the original
; PHP FCGI (5.2.2+). Makes sense only with a tcp listening socket. Each address
; must be separated by a comma. If this value is left blank, connections will be
; accepted from any ip address.
; Default Value: any
;listen.allowed_clients = 127.0.0.1
; Set permissions for unix socket, if one is used. In Linux, read/write
; permissions must be set in order to allow connections from a web server. Many
; BSD-derived systems allow connections regardless of permissions.
; Default Values: user and group are set as the running user
; mode is set to 0666
listen.owner = www
listen.group = www
listen.mode = 0600
; Unix user/group of processes
; Note: The user is mandatory. If the group is not set, the default user's group
; will be used.
user = www
group = www
; Choose how the process manager will control the number of child processes.
; Possible Values:
; static - a fixed number (pm.max_children) of child processes;
; dynamic - the number of child processes are set dynamically based on the
; following directives:
; pm.max_children - the maximum number of children that can
; be alive at the same time.
; pm.start_servers - the number of children created on startup.
; pm.min_spare_servers - the minimum number of children in 'idle'
; state (waiting to process). If the number
; of 'idle' processes is less than this
; number then some children will be created.
; pm.max_spare_servers - the maximum number of children in 'idle'
; state (waiting to process). If the number
; of 'idle' processes is greater than this
; number then some children will be killed.
; Note: This value is mandatory.
pm = dynamic
; The number of child processes to be created when pm is set to 'static' and the
; maximum number of child processes to be created when pm is set to 'dynamic'.
; This value sets the limit on the number of simultaneous requests that will be
; served. Equivalent to the ApacheMaxClients directive with mpm_prefork.
; Equivalent to the PHP_FCGI_CHILDREN environment variable in the original PHP
; CGI.
; Note: Used when pm is set to either 'static' or 'dynamic'
; Note: This value is mandatory.
pm.max_children = 20
; The number of child processes created on startup.
; Note: Used only when pm is set to 'dynamic'
; Default Value: min_spare_servers + (max_spare_servers - min_spare_servers) / 2
pm.start_servers = 10
; The desired minimum number of idle server processes.
; Note: Used only when pm is set to 'dynamic'
; Note: Mandatory when pm is set to 'dynamic'
pm.min_spare_servers = 5
; The desired maximum number of idle server processes.
; Note: Used only when pm is set to 'dynamic'
; Note: Mandatory when pm is set to 'dynamic'
pm.max_spare_servers = 10
; The number of requests each child process should execute before respawning.
; This can be useful to work around memory leaks in 3rd party libraries. For
; endless request processing specify '0'. Equivalent to PHP_FCGI_MAX_REQUESTS.
; Default Value: 0
pm.max_requests = 500
; The URI to view the FPM status page. If this value is not set, no URI will be
; recognized as a status page. By default, the status page shows the following
; information:
; accepted conn - the number of request accepted by the pool;
; pool - the name of the pool;
; process manager - static or dynamic;
; idle processes - the number of idle processes;
; active processes - the number of active processes;
; total processes - the number of idle + active processes.
; max children reached - number of times, the process limit has been reached,
; when pm tries to start more children (works only for
; pm 'dynamic')
; The values of 'idle processes', 'active processes' and 'total processes' are
; updated each second. The value of 'accepted conn' is updated in real time.
; Example output:
; accepted conn: 12073
; pool: www
; process manager: static
; idle processes: 35
; active processes: 65
; total processes: 100
; max children reached: 1
; By default the status page output is formatted as text/plain. Passing either
; 'html' or 'json' as a query string will return the corresponding output
; syntax. Example:
; http://www.foo.bar/status
; http://www.foo.bar/status?json
; http://www.foo.bar/status?html
; Note: The value must start with a leading slash (/). The value can be
; anything, but it may not be a good idea to use the .php extension or it
; may conflict with a real PHP file.
; Default Value: not set
pm.status_path = /fpm-status-zwei
; The ping URI to call the monitoring page of FPM. If this value is not set, no
; URI will be recognized as a ping page. This could be used to test from outside
; that FPM is alive and responding, or to
; - create a graph of FPM availability (rrd or such);
; - remove a server from a group if it is not responding (load balancing);
; - trigger alerts for the operating team (24/7).
; Note: The value must start with a leading slash (/). The value can be
; anything, but it may not be a good idea to use the .php extension or it
; may conflict with a real PHP file.
; Default Value: not set
ping.path = /ping-zwei
; This directive may be used to customize the response of a ping request. The
; response is formatted as text/plain with a 200 response code.
; Default Value: pong
;ping.response = pong
; The timeout for serving a single request after which the worker process will
; be killed. This option should be used when the 'max_execution_time' ini option
; does not stop script execution for some reason. A value of '0' means 'off'.
; Available units: s(econds)(default), m(inutes), h(ours), or d(ays)
; Default Value: 0
request_terminate_timeout = 0
; The timeout for serving a single request after which a PHP backtrace will be
; dumped to the 'slowlog' file. A value of '0s' means 'off'.
; Available units: s(econds)(default), m(inutes), h(ours), or d(ays)
; Default Value: 0
; request_slowlog_timeout = 15s
; The log file for slow requests
; Default Value: not set
; Note: slowlog is mandatory if request_slowlog_timeout is set
; slowlog = /var/log/php-fpm/$pool.log.slow
; Set open file descriptor rlimit.
; Default Value: system defined value
rlimit_files = 65536
; Set max core size rlimit.
; Possible Values: 'unlimited' or an integer greater or equal to 0
; Default Value: system defined value
rlimit_core = 'unlimited'
; Chroot to this directory at the start. This value must be defined as an
; absolute path. When this value is not set, chroot is not used.
; Note: you can prefix with '$prefix' to chroot to the pool prefix or one
; of its subdirectories. If the pool prefix is not set, the global prefix
; will be used instead.
; Note: chrooting is a great security feature and should be used whenever
; possible. However, all PHP paths will be relative to the chroot
; (error_log, sessions.save_path, ...).
; Default Value: not set
;chroot =
; Chdir to this directory at the start.
; Note: relative path can be used.
; Default Value: current directory or / when chroot
chdir = /dataKM
; Redirect worker stdout and stderr into main error log. If not set, stdout and
; stderr will be redirected to /dev/null according to FastCGI specs.
; Note: on highloaded environement, this can cause some delay in the page
; process time (several ms).
; Default Value: no
catch_workers_output = yes
; Pass environment variables like LD_LIBRARY_PATH. All $VARIABLEs are taken from
; the current environment.
; Default Value: clean env
;env[HOSTNAME] = $HOSTNAME
;env[PATH] = /usr/local/bin:/usr/bin:/bin
;env[TMP] = /tmp
;env[TMPDIR] = /tmp
;env[TEMP] = /tmp
env[ORACLE_HOME] = /usr/lib/oracle/12.1/client64/lib
env[LD_LIBRARY_PATH] = /usr/lib/oracle/12.1/client64/lib
; Additional php.ini defines, specific to this pool of workers. These settings
; overwrite the values previously defined in the php.ini. The directives are the
; same as the PHP SAPI:
; php_value/php_flag - you can set classic ini defines which can
; be overwritten from PHP call 'ini_set'.
; php_admin_value/php_admin_flag - these directives won't be overwritten by
; PHP call 'ini_set'
; For php_*flag, valid values are on, off, 1, 0, true, false, yes or no.
; Defining 'extension' will load the corresponding shared extension from
; extension_dir. Defining 'disable_functions' or 'disable_classes' will not
; overwrite previously defined php.ini values, but will append the new value
; instead.
; Note: path INI options can be relative and will be expanded with the prefix
; (pool, global or /usr)
; Default Value: nothing is defined by default except the values in php.ini and
; specified at startup with the -d argument
;php_admin_value[sendmail_path] = /usr/sbin/sendmail -t -i -f [email protected]
;php_flag[display_errors] = off
;php_admin_value[error_log] = /var/log/fpm-php.www.log
;php_admin_flag[log_errors] = on
;php_admin_value[memory_limit] = 32M
galaxydata.ru
Ускорение и оптимизация PHP-сайта. Какие технологии стоит выбирать при настройке сервера под PHP
Эта статья поможет ответить на вопросы владельцев, разработчиков и системных администраторов PHP-сайтов:
- Как оптимизировать сайт и ускорить его работу?
- С какой скоростью будет и может работать сайт, в соответствии с теми технологиями на которых он будет запущен?
- Какие технологии следует использовать настраивая сервер или VPS?
Типичная проблема: В какой-то момент сайт начинает открываться и работать слишком медленно. Бывает, что хостинговая компания блокирует сайт за превышение нагрузки или перерасход ресурсов. Что же делать в такой ситуации?
Может быть, сайт стал пользоваться слишком высокой посещаемостью или был установлен какой-то ресурсоёмкий модуль, совершается атака или сайт заражен вирусом. Так или иначе, но у всех этих случаев есть кое-что общее и это проблема всех сайтов на всех хостингах.
И если говорить о серверах для PHP, то такой проблемой является способ исполнения php кода, ровно как и другие значимые настройки окружения на сервере.
Не зависимо от того, есть ли проблема в вашем коде или её нет, высокая у вас посещаемость или нет, от настроек сервера зависит очень многое. Что бы все сказанное не звучало пустыми словами и была написана эта статья. В этом обзоре я протестирую только что установленный сайт на одном из самых распространённых движков управления контентом Drupal 7.33.
Для теста выбрана лишь одна составляющая php-хостинга. Мы будем тестировать web-серверы Nginx и Apache2, модули mod_php и php-fpm, версии php php53 и php56, посмотрим, как влияют оптимизаторы apc и opcache на скорость работы сайта.
Конечно, эти параметры лишь часть настроек от которых зависит скорость сайта. Но мы умышлено ограничиваемся этим, что бы не делать обзор бесконечным.
Дано:
- Операционная система Centos 6.7
- Сервер баз данных: MariaDB 10.21
- Все сессии сайтов хранятся в memcache, чтобы убрать влияние скорости установки сессии на скорость работы сайта.
- На всех тестах в качестве frontend выступает web-server nginx 1.93. В случае с Apache2, Nginx выступает в качестве балансировщика, а также для отдачи статики. В конфигурациях без использования Apache2 — непосредственным web-сервером является Nginx
- Конфигурация Nginx и MariaDB содержат множество оптимизаций, направленных на достижение максимальной производительности, но для всех участников теста эти настройки одинаковые и поэтому их влиянием следует пренебречь
- Параметры opcache и apc взяты из рекомендаций Bitrix, так как они оптимальны и универсальны для большинства сайтов
Как будем тестировать?
В локальной сети есть сервер zabbix и его задачи каждую минуту:
- Открывать главную страницу испытуемого сайта, дожидаться определенного содержимого на странице, убеждаться, что ответ от сервера — код 200.
- Следующим шагом идет авторизация в админку сайта, это происходит отправкой соответсвующего POST запроса. Сверка текста и кода ответа на странице с заложенным эталоном. Этот шаг касается почти всех подсистем web-сервера, и во многом его скорость зависит от скорости взаимодействия с базой данных
- Последним шагом является выход из админки сайта, сверка кода ответа и текста на странице выхода
- По итогам каждого шага, zabbix будет скрупулезно замерять и записывать скорость рендеринга php-кода в html понятный браузеру и демонстрировать нам графики полученных результатов
- Для каждого испытуемого будут записываться значения в течение одного часа и в качестве результата будет выступать средние значения за этот час
- Тестирование будет происходить внутри локальной сети, так что влияние на результат скорости интернет-соединения исключено
- Для удобства восприятия, все результаты показываю в порядке возрастания. Т.е. самый первый результат — это самый медленный. Все конфигурации были вынесены под условный номер, это позволит лучше ориентироваться в результатах
- Верхние графики — скорость генерации кода, чем выше значение, тем лучше. Нижние графики — время ответа сервера и чем ниже значение, тем лучше
- Тестируемые сайты живут своей жизнью, в них происходят регулярные операции с базами данных и выполняются задания по расписанию, именно поэтому кривая на графиках может иметь взлеты и падения
Тестирование:
1. Nginx + php-fpm56 без оптимизатора opcache
По архитектуре — это один из самых передовых вариантов. По производительности — наибольшее разочарование. Производительность оставляет желать лучшего, но нагрузку такой вариант будет выдерживать гораздо лучше чем вариант №2 с Apache2. Так же, такой вариант будет расходовать оперативную память существенно эффективнее.
2. Apache2 + mod_php53 без оптимизатора apc
Cамый типичный для хостингов вариант. 90% популярных хостинг-провайдеров используют этот вариант. Хоть php53 давно не поддерживается разработчиками, но в интернете очень много сайтов, до сих пор работающих на этой версии. Такой вариант не только очень медленный, но и быстро падает под небольшой нагрузкой из-за нехватки рабочих процессов Apache2, либо из-за нехватки оперативной памяти на сервере.
3. Балансировка и статика через Nginx, динамическая часть Apache2 + mod_php56 без оптимизатора opcache
Этот вариант создан как решение для современных сайтов. Его предлагают хостинги, которые стремятся предоставлять свежую версию PHP. Согласно бытующему мнению, эта версия PHP должна быть более быстрой и безопасной, чем предыдущие. К сожалению, далеко не все сайты могут работать полноценно c этой версией. Почти каждая новая версия PHP перестает поддерживать некоторые устаревшие и «небезопасные» функции, нарушая работу «старого» кода.Сам по себе php56 без оптимизатора довольно медленный, а mod_php склонен падать и занимать всю память на сервере под нагрузкой.
4. Nginx + php-fpm53 без оптимизатора apc
Достаточно передовая конфигурация, для тех кто не желает иметь проблемы из-за ошибок с оптимизатором кода. При этом используется «совместимая» версия интерпретатора PHP, а также из связки убирается ресурсоемкий Apache2.
5. Балансировка и статика через Nginx, динамическая часть Apache2 + mod_php53 + apc
Еще одна распространенная вариация. Очень многие хостинги применяют именно её, при этом либо используют по умолчанию, либо дают возможность включать оптимизатор в своих панелях управления.Обычно Apache2 оставляют для работы .htaccess-правил, таких как преобразование ссылок и ЧПУ. Получаем прирост скорости в 3,5 раза, по сравнению с вариантом без использования оптимизатора. Сам по себе Apache (при использовании его собственного модуля mod_php) расходует для свой работы гораздо больше ресурсов, чем вариант с php-fpm. Apache2 склонен падать, если в одном из его модулей случается сбой или заполнять собой всю оперативную память сервера.
6. Nginx + php-fpm53 + apc
Отличный вариант для сайтов на старых движках, не требующих сложных .htaccess Именно такой вариант я использую, когда необходимо поднять устаревший сайт, добиться от него удовлетворительной скорости и надежной работы при высоких нагрузках.
7. Балансировка и статика через Nginx, динамическая часть Apache2 + php-fpm53 + apc
Вариант для устаревших сайтов со сложными .htaccess. Например — старые инсталляции Bitrix. Это идеальный вариант для устаревших сайтов. Данная конфигурация устойчива к высоким нагрузкам, совместима и достаточно производительна.Отлично подходит, когда нужны правила .htaccess и дополнительные модули Apache2. Из недостатков — устаревшая и не обновляемая версия php, но если нет выбора — это самый лучший вариант. Отлично подходит для старой версий Bitrix, Joomla и других распространенных CMS не самых свежих версий.
8. Балансировка и статика через Nginx, динамическая часть Apache2 + mod_php56 + opcache
Достаточно производительная, но ресурсоёмкая конфигурация со всеми недостатками mod_php. Достаточно быстро, но под нагрузкой у сервера может закончится память, а скорость существенно упадет.
9. Nginx + php-fpm56 + opcache
Самый производительный вариант. Это самый лучший вариант для всех современных сайтов. Хорошо держит нагрузку, показывает самый лучший результат с точки зрения производительности. Именно такой вариант я использую, когда стоит задача оптимизировать производительность сайта и увеличить скорость его работы.Единственный недостаток — это то, что мы не сможем использовать .htaccess и все правила mod_rewrite нужно переписать на синтаксис Nginx.Также не будут работать модули Apache2. Если таковые используются, то этот вариант не подойдёт.
10. Балансировка и статика через Nginx, динамическая часть Apache2 + php-fpm56+ opcache
Самый лучший вариант для сайтов, где нужен .htaccess. Идеально подходит для свежих версий Bitrix. Хорошо держит нагрузку за счет php-fpm. Активно использую этот вариант для большинства сайтов.
Главная страница тестового сайта | |||
Номер конфигурации | Архитектура | Средняя скорость загрузки кб. | Средний отклик мс. |
1 | Nginx + php-fpm56 без оптимизатора opcache | 77,04 | 103,6 |
2 | Apache2 + mod_php53 без оптимизатора apc | 78,79 | 103,98 |
3 | Apache2 + mod_php56 без оптимизатора opcache | 78,85 | 102,38 |
4 | Nginx + php-fpm53 без оптимизатора apc | 81,55 | 97,88 |
5 | Apache2 + mod_php53 + apc | 303,37 | 29,36 |
6. | Nginx + php-fpm53 + apc | 312,33 | 24,73 |
7. | Apache2 + php-fpm53 + apc | 339,63 | 23,32 |
8. | Apache2 + mod_php56 + opcache | 484,96 | 16,91 |
9. | Nginx + php-fpm56 + opcache | 546,34 | 14,08 |
10. | Apache2 + php-fpm56+ opcache | 571,14 | 13,78 |
Авторизация в админке тестового сайта | |||
Номер конфигурации | Архитектура | Средняя скорость загрузки кб. | Средний отклик мс. |
1 | Nginx + php-fpm56 без оптимизатора opcache | 67,51 | 239,01 |
2 | Apache2 + mod_php53 без оптимизатора apc | 64,61 | 257,51 |
3 | Apache2 + mod_php56 без оптимизатора opcache | 66,75 | 242,42 |
4 | Nginx + php-fpm53 без оптимизатора apc | 68.79 | 233.15 |
5 | Apache2 + mod_php53 + apc | 173,81 | 94,26 |
6. | Nginx + php-fpm53 + apc | 173,3 | 91,3 |
7. | Apache2 + php-fpm53 + apc | 182,1 | 90,5 |
8. | Apache2 + mod_php56 + opcache | 218,35 | 77,55 |
9. | Nginx + php-fpm56 + opcache | 252,83 | 62,25 |
10. | Apache2 + php-fpm56+ opcache | 262,8 | 60,85 |
Выход из админки тестового сайта | |||
Номер конфигурации | Архитектура | Средняя скорость загрузки кб. | Средний отклик мс. |
1 | Nginx + php-fpm56 без оптимизатора opcache | 41,01 | 184,49 |
2 | Apache2 + mod_php53 без оптимизатора apc | 42,42 | 188,97 |
3 | Apache2 + mod_php56 без оптимизатора opcache | 42,06 | 188,37 |
4 | Nginx + php-fpm53 без оптимизатора apc | 45,48 | 169,15 |
5 | Apache2 + mod_php53 + apc | 190,1 | 41,87 |
6. | Nginx + php-fpm53 + apc | 185,92 | 41,24 |
7. | Apache2 + php-fpm53 + apc | 202,78 | 39,21 |
8. | Apache2 + mod_php56 + opcache | 315,56 | 26,23 |
9. | Nginx + php-fpm56 + opcache | 373,19 | 20,43 |
10. | Apache2 + php-fpm56+ opcache | 381,21 | 20,57 |
В качестве итогов:
- В реальной жизни, все варианты с Apache2 могут быть медленней, так как в своих тестах я умышленно передал отдачу статики Nginx. Это сделано, чтобы исключить влияние скорости отдачи статики на результаты замера скорости работы интерпретатора PHP. Одной из наиболее слабой стороной Apache2 и при этом сильной Nginx — является скорость отдачи статики. Особенно, это заметно на высоких нагрузках. Кроме того, Nginx менее подвержен атаке «медленных соединений»
- php56 без оптимизатора — медленней чем php53 без оптимизатора
- php56 c opcache — значительно быстрее php53 c apc
- mod_php очень быстро занимает всю доступную память сервера и теряет производительность на нагрузках
- php-fpm расходует память значительно эффективнее, безопаснее и гибче в настройках. В ряде случаев он быстрее и без высоких нагрузок.
- Тест имеет узкую специфику, тут мы увидели особенности работы движка Drupal, другие могут вести себя иначе, но общая тенденция будет такой же.
И главное — от конфигурации вашего сервера или хостинга, зависит скорость вашего сайта. Подобрав верную архитектуру, вы можете получить пятикратное увеличение скорости работы сайта.
Если у вас возникнут вопросы, трудности или потребуется совет:Мои контакты в профиле
myitnews.ru
настройка и оптимизация php для больших нагрузок - Записки сумасшедшего
Куда все свои запросы передает nginx? на php, вот его настройки и проверим.
php.ini
Начнем с php.ini
memory_limit = 32M это значение по умолчанию, и чем оно больше, тем меньше у вас останется оперативной памяти, увеличивать его стоит, только если у Вас очень тяжелые срипты.
zlib.output_compression = Off, zlib.output_compression_level = -1 выключаем сжатие на стороне обработчика скриптов, пусть этим занимается наш nginx
max_execution_time = 5 если у вас скрипты выполняются более 5 секунд, задумайтесь над их оптимизацией.
zend.enable_gc = On сервер будет сам оптимизировать память в фоне.
expose_php = Off это больше для безопасности, сервер не будет отдавать в ответах свою версию
report_memleaks = On заставит сервер писать в лог про утечки в памяти
post_max_size = 4M, upload_max_filesize = 4M это максимальный размер закачки файла,
по умолчанию, php хранит сессии в файле, но более происводительным от будет, если отдать это хранение в некий обработчик, этим самым обработчиком является memcache
просто установите данное расширение
apt-get install memcached php5-memcacheи внесите изменениея в php.ini
session.save_handler = memcache session.save_path = "tcp://localhost:11211"Так как у меня почти везде nginx+php5-fpm то покрутим гайки у пула php5-fpm
# Динамический менеджер рабочих процессов будет поддерживать от 10 до 30 процессов, # из которых от 5 до 10 могут простаивать в ожидании поступления новых запросов. # Если простаивающих процессов будет меньше 5 - будут порождены новые процессы, # если простаивающих процессов окажется больше 10 - лишние будут завершены pm = dynamic pm.max_children = 30 pm.start_servers = 10 pm.min_spare_servers = 5 pm.max_spare_servers = 10 # Ограничем количество запросов, последовательно обслуживаемых одним процессом # После этого процесс будет завершён и запущен снова - это может помочь от утечек памяти pm.max_requests = 200 # Если обработка одного запроса длится дольше двух минут - обработка запроса принудительно завершается request_terminate_timeout = 120s # В этом файле ведём журнал обработанных запросов access.log = /var/log/slow-php5-fpm.access.log # Тут задем настройка для каждого отдельного пула, которые отличаются от тех, что в php.ini # Настройки php_admin нельзя поменять изнутри самого PHP-приложения php_value[data.timezone] = Europe/Moscow php_admin_flag[log_errors] = on php_admin_value[error_log] = /var/log/php5-fpm.errors.log #php_admin_value[memory_limit] = 128M php_admin_value[mysql.connect_timeout] = 1
blog.n1mda.ru
H Ускорение и оптимизация PHP-сайта. Какие технологии стоит выбирать при настройке сервера под PHP
![](/img/optimizaciya-php-fpm_11.jpg)
Эта статья поможет ответить на вопросы владельцев, разработчиков и системных администраторов PHP-сайтов:
- Как оптимизировать сайт и ускорить его работу?
- С какой скоростью будет и может работать сайт, в соответствии с теми технологиями на которых он будет запущен?
- Какие технологии следует использовать настраивая сервер или VPS?
Типичная проблема: В какой-то момент сайт начинает открываться и работать слишком медленно. Бывает, что хостинговая компания блокирует сайт за превышение нагрузки или перерасход ресурсов. Что же делать в такой ситуации?
Может быть, сайт стал пользоваться слишком высокой посещаемостью или был установлен какой-то ресурсоёмкий модуль, совершается атака или сайт заражен вирусом. Так или иначе, но у всех этих случаев есть кое-что общее и это проблема всех сайтов на всех хостингах.
И если говорить о серверах для PHP, то такой проблемой является способ исполнения php кода, ровно как и другие значимые настройки окружения на сервере. Не зависимо от того, есть ли проблема в вашем коде или её нет, высокая у вас посещаемость или нет, от настроек сервера зависит очень многое. Что бы все сказанное не звучало пустыми словами и была написана эта статья.
В этом обзоре я протестирую только что установленный сайт на одном из самых распространённых движков управления контентом Drupal 7.33.
Для теста выбрана лишь одна составляющая php-хостинга. Мы будем тестировать web-серверы Nginx и Apache2, модули mod_php и php-fpm, версии php php53 и php56, посмотрим, как влияют оптимизаторы apc и opcache на скорость работы сайта.
Конечно, эти параметры лишь часть настроек от которых зависит скорость сайта. Но мы умышлено ограничиваемся этим, что бы не делать обзор бесконечным.
Дано:
- Операционная система Centos 6.7
- Сервер баз данных: MariaDB 10.21
- Все сессии сайтов хранятся в memcache, чтобы убрать влияние скорости установки сессии на скорость работы сайта.
- На всех тестах в качестве frontend выступает web-server nginx 1.93. В случае с Apache2, Nginx выступает в качестве балансировщика, а также для отдачи статики. В конфигурациях без использования Apache2 — непосредственным web-сервером является Nginx
- Конфигурация Nginx и MariaDB содержат множество оптимизаций, направленных на достижение максимальной производительности, но для всех участников теста эти настройки одинаковые и поэтому их влиянием следует пренебречь
- Параметры opcache и apc взяты из рекомендаций Bitrix, так как они оптимальны и универсальны для большинства сайтов
Как будем тестировать?
В локальной сети есть сервер zabbix и его задачи каждую минуту:
- Открывать главную страницу испытуемого сайта, дожидаться определенного содержимого на странице, убеждаться, что ответ от сервера — код 200.
- Следующим шагом идет авторизация в админку сайта, это происходит отправкой соответсвующего POST запроса. Сверка текста и кода ответа на странице с заложенным эталоном. Этот шаг касается почти всех подсистем web-сервера, и во многом его скорость зависит от скорости взаимодействия с базой данных
- Последним шагом является выход из админки сайта, сверка кода ответа и текста на странице выхода
- По итогам каждого шага, zabbix будет скрупулезно замерять и записывать скорость рендеринга php-кода в html понятный браузеру и демонстрировать нам графики полученных результатов
- Для каждого испытуемого будут записываться значения в течение одного часа и в качестве результата будет выступать средние значения за этот час
- Тестирование будет происходить внутри локальной сети, так что влияние на результат скорости интернет-соединения исключено
- Для удобства восприятия, все результаты показываю в порядке возрастания. Т.е. самый первый результат — это самый медленный. Все конфигурации были вынесены под условный номер, это позволит лучше ориентироваться в результатах
- Верхние графики — скорость генерации кода, чем выше значение, тем лучше. Нижние графики — время ответа сервера и чем ниже значение, тем лучше
- Тестируемые сайты живут своей жизнью, в них происходят регулярные операции с базами данных и выполняются задания по расписанию, именно поэтому кривая на графиках может иметь взлеты и падения
Тестирование:
1. Nginx + php-fpm56 без оптимизатора opcache
По архитектуре — это один из самых передовых вариантов. По производительности — наибольшее разочарование.
Производительность оставляет желать лучшего, но нагрузку такой вариант будет выдерживать гораздо лучше чем вариант №2 с Apache2. Так же, такой вариант будет расходовать оперативную память существенно эффективнее.
2. Apache2 + mod_php53 без оптимизатора apc
Cамый типичный для хостингов вариант. 90% популярных хостинг-провайдеров используют этот вариант. Хоть php53 давно не поддерживается разработчиками, но в интернете очень много сайтов, до сих пор работающих на этой версии.
Такой вариант не только очень медленный, но и быстро падает под небольшой нагрузкой из-за нехватки рабочих процессов Apache2, либо из-за нехватки оперативной памяти на сервере.
3. Балансировка и статика через Nginx, динамическая часть Apache2 + mod_php56 без оптимизатора opcache
Этот вариант создан как решение для современных сайтов. Его предлагают хостинги, которые стремятся предоставлять свежую версию PHP. Согласно бытующему мнению, эта версия PHP должна быть более быстрой и безопасной, чем предыдущие.
К сожалению, далеко не все сайты могут работать полноценно c этой версией. Почти каждая новая версия PHP перестает поддерживать некоторые устаревшие и «небезопасные» функции, нарушая работу «старого» кода. Сам по себе php56 без оптимизатора довольно медленный, а mod_php склонен падать и занимать всю память на сервере под нагрузкой.
4. Nginx + php-fpm53 без оптимизатора apc
Достаточно передовая конфигурация, для тех кто не желает иметь проблемы из-за ошибок с оптимизатором кода. При этом используется «совместимая» версия интерпретатора PHP, а также из связки убирается ресурсоемкий Apache2.
5. Балансировка и статика через Nginx, динамическая часть Apache2 + mod_php53 + apc
Еще одна распространенная вариация. Очень многие хостинги применяют именно её, при этом либо используют по умолчанию, либо дают возможность включать оптимизатор в своих панелях управления. Обычно Apache2 оставляют для работы .htaccess-правил, таких как преобразование ссылок и ЧПУ.
Получаем прирост скорости в 3,5 раза, по сравнению с вариантом без использования оптимизатора. Сам по себе Apache (при использовании его собственного модуля mod_php) расходует для свой работы гораздо больше ресурсов, чем вариант с php-fpm. Apache2 склонен падать, если в одном из его модулей случается сбой или заполнять собой всю оперативную память сервера.
6. Nginx + php-fpm53 + apc
Отличный вариант для сайтов на старых движках, не требующих сложных .htaccess
Именно такой вариант я использую, когда необходимо поднять устаревший сайт, добиться от него удовлетворительной скорости и надежной работы при высоких нагрузках.
7. Балансировка и статика через Nginx, динамическая часть Apache2 + php-fpm53 + apc
Вариант для устаревших сайтов со сложными .htaccess. Например — старые инсталляции Bitrix.
Это идеальный вариант для устаревших сайтов. Данная конфигурация устойчива к высоким нагрузкам, совместима и достаточно производительна. Отлично подходит, когда нужны правила .htaccess и дополнительные модули Apache2. Из недостатков — устаревшая и не обновляемая версия php, но если нет выбора — это самый лучший вариант. Отлично подходит для старой версий Bitrix, Joomla и других распространенных CMS не самых свежих версий.
8. Балансировка и статика через Nginx, динамическая часть Apache2 + mod_php56 + opcache
Достаточно производительная, но ресурсоёмкая конфигурация со всеми недостатками mod_php.
Достаточно быстро, но под нагрузкой у сервера может закончится память, а скорость существенно упадет.
9. Nginx + php-fpm56 + opcache
Самый производительный вариант.
Это самый лучший вариант для всех современных сайтов. Хорошо держит нагрузку, показывает самый лучший результат с точки зрения производительности. Именно такой вариант я использую, когда стоит задача оптимизировать производительность сайта и увеличить скорость его работы. Единственный недостаток — это то, что мы не сможем использовать .htaccess и все правила mod_rewrite нужно переписать на синтаксис Nginx. Также не будут работать модули Apache2. Если таковые используются, то этот вариант не подойдёт.
10. Балансировка и статика через Nginx, динамическая часть Apache2 + php-fpm56+ opcache
Самый лучший вариант для сайтов, где нужен .htaccess. Идеально подходит для свежих версий Bitrix.
Хорошо держит нагрузку за счет php-fpm. Активно использую этот вариант для большинства сайтов.
Главная страница тестового сайта | |||
Номер конфигурации | Архитектура | Средняя скорость загрузки кб. | Средний отклик мс. |
1 | Nginx + php-fpm56 без оптимизатора opcache | 77,04 | 103,6 |
2 | Apache2 + mod_php53 без оптимизатора apc | 78,79 | 103,98 |
3 | Apache2 + mod_php56 без оптимизатора opcache | 78,85 | 102,38 |
4 | Nginx + php-fpm53 без оптимизатора apc | 81,55 | 97,88 |
5 | Apache2 + mod_php53 + apc | 303,37 | 29,36 |
6. | Nginx + php-fpm53 + apc | 312,33 | 24,73 |
7. | Apache2 + php-fpm53 + apc | 339,63 | 23,32 |
8. | Apache2 + mod_php56 + opcache | 484,96 | 16,91 |
9. | Nginx + php-fpm56 + opcache | 546,34 | 14,08 |
10. | Apache2 + php-fpm56+ opcache | 571,14 | 13,78 |
Авторизация в админке тестового сайта | |||
Номер конфигурации | Архитектура | Средняя скорость загрузки кб. | Средний отклик мс. |
1 | Nginx + php-fpm56 без оптимизатора opcache | 67,51 | 239,01 |
2 | Apache2 + mod_php53 без оптимизатора apc | 64,61 | 257,51 |
3 | Apache2 + mod_php56 без оптимизатора opcache | 66,75 | 242,42 |
4 | Nginx + php-fpm53 без оптимизатора apc | 68.79 | 233.15 |
5 | Apache2 + mod_php53 + apc | 173,81 | 94,26 |
6. | Nginx + php-fpm53 + apc | 173,3 | 91,3 |
7. | Apache2 + php-fpm53 + apc | 182,1 | 90,5 |
8. | Apache2 + mod_php56 + opcache | 218,35 | 77,55 |
9. | Nginx + php-fpm56 + opcache | 252,83 | 62,25 |
10. | Apache2 + php-fpm56+ opcache | 262,8 | 60,85 |
Выход из админки тестового сайта | |||
Номер конфигурации | Архитектура | Средняя скорость загрузки кб. | Средний отклик мс. |
1 | Nginx + php-fpm56 без оптимизатора opcache | 41,01 | 184,49 |
2 | Apache2 + mod_php53 без оптимизатора apc | 42,42 | 188,97 |
3 | Apache2 + mod_php56 без оптимизатора opcache | 42,06 | 188,37 |
4 | Nginx + php-fpm53 без оптимизатора apc | 45,48 | 169,15 |
5 | Apache2 + mod_php53 + apc | 190,1 | 41,87 |
6. | Nginx + php-fpm53 + apc | 185,92 | 41,24 |
7. | Apache2 + php-fpm53 + apc | 202,78 | 39,21 |
8. | Apache2 + mod_php56 + opcache | 315,56 | 26,23 |
9. | Nginx + php-fpm56 + opcache | 373,19 | 20,43 |
10. | Apache2 + php-fpm56+ opcache | 381,21 | 20,57 |
В качестве итогов:
- В реальной жизни, все варианты с Apache2 могут быть медленней, так как в своих тестах я умышленно передал отдачу статики Nginx. Это сделано, чтобы исключить влияние скорости отдачи статики на результаты замера скорости работы интерпретатора PHP. Одной из наиболее слабой стороной Apache2 и при этом сильной Nginx — является скорость отдачи статики. Особенно, это заметно на высоких нагрузках. Кроме того, Nginx менее подвержен атаке «медленных соединений»
- mod_php очень быстро занимает всю доступную память сервера и теряет производительность на нагрузках
- php-fpm расходует память значительно эффективнее, безопаснее и гибче в настройках. В ряде случаев он быстрее и без высоких нагрузок.
- Тест имеет узкую специфику, тут мы увидели особенности работы движка Drupal, другие могут вести себя иначе, но общая тенденция будет такой же.
И главное — от конфигурации вашего сервера или хостинга, зависит скорость вашего сайта. Подобрав верную архитектуру, вы можете получить пятикратное увеличение скорости работы сайта.
Если у вас возникнут вопросы, трудности или потребуется совет: Мои контакты в профиле
sohabr.net