Как найти причину падения производительности приложения (apache, php, mysql)?

В локальной сети есть сайт, на котором сотрудники ведут документооборот.
Сотрудники вносят данные посетителей, плюс фоновые скрипты вносят свои данные - всего в среднем 70 запросов в БД в секунду. Это работает на PHP 7.2, MySQL 5.7, Apache 2.4 на Windows Server 2012 r2. Приложение пишется на нативном PHP с 2015 года, постепенно усложняясь.

В последнее время периодически в течение дня производительность сильно проседает. Как и чем спровоцировать такое падение (для изучения в лабораторных условиях) я не понимаю.

Что происходит: 32 ядра виртуальной машины получают нагрузку в 90% (память при этом свободная), запросы в БД почти все выпадают в лог медленных запросов со значением 5-10-80 секунд вместо обычных 0.1-0.5-1.

Как лечим: перезапускаем apache (метод найден опытным путем, перезапуск остального не меняет ситуацию).
На какое-то время хватает, потом проблема снова повторяется. Или не повторяется и сервер спокойно живет несколько дней.

Есть несколько гипотез (автокоммит, штатные фоновые запросы на запись по 6-10 секунд), но все они требуют переписывания приложения, а не факт, что поможет.

Прошу помощи! Подскажите, как определить проблему? Какие есть инструменты диагностики?
  • Вопрос задан
  • 549 просмотров
Пригласить эксперта
Ответы на вопрос 6
profesor08
@profesor08
Плохо оптимизированная работа с бд и плохая структура бд приводит к таким результатам. Начинать надо с самого приложения и постепенно оптимизировать код так, чтоб за раз выполнялся один запрос на выборку данных и один на их обновление. Если запросов несколько сотен, то группировать по сотне и отправлять (или по тысячи, проверять эмпирическим путем).
Ответ написан
@vitaly_il1
DevOps Consulting
запросы в БД почти все выпадают в лог медленных запросов со значением 5-10-80 секунд вместо обычных 0.1-0.5-1.

Начать оптимизировать запросы - 0.5-1 в 90% это много == излишняя нагрузка на CPU/disk.

Я бы также разнес веб и MySQL по разным машинам, будет легче анализировать и оптимизировать.
Плюс - создать реплику и запросы на чтение посылать туда.
Ответ написан
@part_os
привет. приходится оптимизировать иногда процессы. дам совет. Не оптимизирует в слепую. Вот инструмент XHProf который поможет вам понят узкие места. Можно использовать на боевом. https://github.com/tideways/php-xhprof-extension
Ответ написан
@SergeyNN Автор вопроса
Промежуточный ответ

Пока ограничился такими мерами:
- убрал профайлинг запросов (был включен всё это время оказалось еще со времен разработки);
- поправил настройки кеша и т.п. для mysql по рекомендациям с хайлоад.ру.;
- понизил степень сжатия gzip в апаче с 9 до 3 (это, как я думаю, самое влиятельное изменение на тормоза апача сейчас).

При этом, как оказалось, запросов в секунду производится не 70, а 1000. Как я так раньше насчитал - не могу сказать :).
Из этой 1000 процентов 90% - повторные попытки поставить в очередь отправку/прием данных со сторонней системы, которая в последнее время сбоит. Но это отдельная нагрузка от фоновых скриптов, она идет не через пожирающий процессор апач.

Тем не менее, даже сейчас при этой 1000 запросов в секунду с указанными выше изменениями всё работает весьма стабильно. Загрузка проца в среднем 30-50% и только от Апача. Объем потребляемой памяти не вырос.

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

Конечно, нужно пересматривать архитектуру, разносить базы по чтению и записи, но это точно не в это лето.

Обязательно отпишусь по достижению каких-либо принципиальных изменений.

Спасибо всем за полезные советы!
Ответ написан
2ord
@2ord
продвинутый чайник
Судя по описанным симптомам, приложение является виновником и похоже, что СУБД в данном случае подолгу держит соединения открытыми. В результате веб-сервер вынужден держать сообщение с клиентом пока не получит ответ от приложения. В СУБД возможно отсутствуют необходимые индексы в таблицах, из-за чего она выполняет больше работы.
Без мониторинга приложения не будет полной картины. Первым делом нужно интегрировать NewRelic или аналог. Тогда будет ясно какие запросы дорогие на наглядных графиках и какие части нужно оптимизировать или вовсе переделывать.
Только тогда принимать решение о разнесении СУБД и веб-сервера с веб-приложением.
Ответ написан
@sergeyiljin
Делаю дело
1) С Apache перейти на Nginx в Linux.
2) Оптимизировать узкие места при работе с СУБД.
3) В идеале перейти с PHP на более производительную платформу, например .NET Core 3.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы