Оптимизация производительности
Для решения проблем производительности, необходимо последовательно на разных уровнях выявить и устранить узкие места.
Сервер
Каждый запрос пользователя к ПО (сеанс работы с системой) расходует ресурсы сервера. При одновременной работе многих пользователей с ПО свободные ресурсы сервера могут закончиться. Это будет проявляться в медленной работе ПО (равно для операций чтения и записи).
Предварительно, необходимо убедиться, что при нормальной (обычной) нагрузке на сервере остаются свободными 20%-30% оперативной памяти.
Работа ПО связана с интенсивным обращением к дискам (СУБД, файловый кеш). Необходимо убедиться, что дисковая подсистема справляется и не формируются длинные очереди ожидания операций чтения/записи.
Иногда задержки могут быть связаны с проблемами сетевого характера.
Веб-сервер
Для анализа загрузки веб-сервера Apache используется штатный модуль mod_status, информация от которого доступна по пути http://сервер/server-status
Информация чувствительная, поэтому по умолчанию доступ к этому модулю ограничен. Чтобы снять ограничения, выполните настройку веб-сервера:
<Location /server-status>
SetHandler server-status
Order Allow,Deny
Allow from all
Require all granted
</Location>
Анализ информации осуществляется следующим образом:
- Оцениваем количество доступных слотов для подключения (1 на скриншоте ниже). Точки и подчеркивания - это доступные слоты, буквы - занятые слоты. При нормальной нагрузке должны быть доступными 50% слотов для подключений к веб-серверу.
- Оцениваем время обработки запроса PHP-процессором (2 на скриншоте ниже). Большое время говорит о наличии проблем на уровне приложения или СУБД.
- Однако, необходимо также проверить запросы к файлам (не приложению), например, загрузку JS или таблиц стилей (CSS) - 3 на скриншоте ниже. Если медленно загружаются эти файлы (статика), то проблема на уровне веб-сервера. Например, может быть некорректно сконфигурирован php-fpm, его таймауты или ограничения по числу подключений, формируют узкое место в приложении.
При большом количестве одновременно работающих пользователей может не хватать доступных слотов для подключения к веб-серверу. Выражается это в том, что пользователь ожидает ответа от сервера, но до приложения запрос не доходит, а стоит в очереди. Для управления настройкой доступных слотов необходимо конфигурировать модуль mpm_prefork.conf
Ниже представлен один из вариантов конфигурации:
<IfModule mpm_prefork_module>
StartServers 5
MinSpareServers 5
MaxSpareServers 15
ServerLimit 900
MaxClients 900
MaxRequestsPerChild 150
</IfModule>
При использовании PHP-FPM настройка количества слотов осуществляется в файле /etc/php-fpm.d/www.conf
Необходимо установить параметр max_children, например, следующим образом:
pm.max_children = 900
Приложение
Само приложение вряд ли будет являться узким местом, поскольку не обращается ни к каким внешним ресурсам, кроме СУБД. Однако, возможны неоптимальные запросы, которые требуют оптимизации силами разработчиков.
СУБД
Для анализа производительности СУБД лучше всего начать с простых проверок. Необходимо подключиться к СУБД и выполнить запрос:
show processlist;
Необходимо проанализировать перечень текущих запросов под нормальной нагрузкой:
- В столбце Time отображается время выполнения запроса в секундах. Большое значение - это признак потенциальной проблемы. Однако, необходимо учитывать, что иногда запросы по природе своей могут быть тяжелыми (долгими), например, когда запрашивается большой объем данных. Проблема в работе СУБД - это медленно выполняющийся простой запрос.
- Блокировки иногда являются причиной долгого выполнения запросов. Блокировки могут быть вызываны ошибками в работе СУБД (требуется перезагрузка), либо ошибками в работе приложения (требуется оптимизация приложения).
Если в режиме реального времени не удается обнаружить аномальную нагрузку, то необходимо включить логирование запросов в конфигурационном файле, например, /etc/mysql/conf.d/z-devprom.conf
slow_query_log = 1
slow_query_log_file = /var/log/mysql/mysql-slow.log
long_query_time = 5
После перезапуска MySQL в указанном логе будут собираться запросы, которые выполнялись более 5 секунд.
Если обнаруживаются медленные запросы (Query_time, сек.), при обработке которых затрагивалось небольшое количество строк (Rows_examined) - это признак наличия узких мест на сервере (отсутствие доступных ресурсов сервера, либо медленая дисковая подсистема). Неоптимальное использование ресурсов сервера также может быть вызывано недостаточной оптимизацией самой СУБД, которая выполняется различными настройками (кеши разных уровней).