Сайт периодически зависает (php-fpm Finishing)

Репорт: сайт периодически тормозит, не грузится.

Действительно, пытаешься зайти на сайт, он то открывается, то нет. Чаще нет. Что замечательно, по админке ходится нормально. Соответственно, подозрения падают на новую тему.

Второй взгляд: сайт периодически блокируется по php-fpm, кончаются свободные воркеры.

А «тормозит» и «висит» сайт потому, что все 16 выделенных php-fpm воркеров заняты. Чем-то заняты. Неизвестно, чем. Но они пока не готовы принимать новые запросы, поэтому и висим.

Это мы видим через htop при php-fpm pm = dynamic, количество воркеров в спокойном состоянии будет не больше pm.max_spare_servers = 8,  а не все 16 процессов, которые видны в списке.

Третий взгляд: много воркеров php-fpm висит на статусе Finishing.

Мы знаем, что у Апача есть статус монитор, можно зайти на специальную страницу и увидеть, что там происходит с воркерами, заняты ли они. Стандартная настройка примерно такая:

, самое простое — открыть доступ для локального клиента. Значит через ssh на сервере мы можем выполнить команду вроде lynx localhost/mystatus и увидеть статусы воркеров.

Для пхп же всё не так просто. php-fpm как бы позволяет настроить подобную штуку:

, но прямого доступа к php-fpm у нас же нет, всё ловит апач. И когда пытаешься обратиться к такой ссылке, ничего не получается. К счастью, здесь нам помогает гугл и добрые люди, работает такая команда:

 

Если биндинг апача и пхп-фпм не через сокет, а по tcp, то там вместо адреса сокета нужно указать адрес. QUERY_STRING можно менять на свой вкус:

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

 

Воркеры php-fpm выглядят так, если всё работает нормально

Так выглядят воркеры сейчас, когда всё работает нормально. Или Running, или Idle. А там было Finishing, всё висело на нём. Причём чтобы получить вот такую картину, это тоже нужно присоединиться к воркеру, хотя бы один должен остаться свободен. У меня настроены таймауты request_terminate_timeout = 70s, поэтому рано или поздно хотя бы один освободится.

Finishing. И что делать дальше?

Воспроизводим проблему

Проблема достаточно волшебная, повторяется только на определённой версии Safari. В developer console видно, что происходит. Там куча 404 для шрифтов. Причём в отличие от Хрома, сафари пытается загрузить все варианты шрифтов что видит, не важно что они не используются на текущей странице.

Вот как это выглядит со стороны сервера, обратите внимание на неравномерные секунды в самой левой колонке: строчка в лог апача добавляется в момент, когда реквест выполнен до конца, а пишется время начала запроса. Видно, что некоторые запросы начались раньше, а закончились позже других. Такой неравномерности быть не должно, в нормальных случаях не наблюдается.

 

Причём, почему-то виснет именно процесс 404 для определённого браузера. Именно для залогиненного админа.

strace

strace это волшебная утилита. Можно наживую присоединиться к процессу php-fpm, который в данный момент Finishing и попробовать понять, на чём он там завис.

Подключаемся: strace -p 21424

Видим:

 

Причём сначала висит текст где-то до -1 ECONNRESET (Connection reset by peer), затем через секунд 5+ выводится как раз -1 ECONNRESET (Connection reset by peer) и всё остальное быстро-быстро, и процесс завершается.

То есть понятно, что задержки вызваны тем, что что-то пытается куда-то подключиться и отваливается. Может быть к БД (там всё хорошо, хз), может быть к какому-то внешнему ресурсу.

 

Виновник

А ещё мы видим, что рядом с -1 ECONNRESET (Connection reset by peer) находится аутпут html очень похожий на аутпут Query Monitor. Может быть дело именно в нём.

Отключаем Query Monitor и действительно, проблема больше не повторяется. Теперь процессы завершаются быстро, а не по 5+ секунд. Ну и осталось избавиться от 404 в ресурсах темы, чтобы не нагружать сервер генерацией 404 страниц.

Ура!

 

P.S.: Почему это проявлялось именно на этом Safari и не проявлялось на остальных я не знаю и скорее всего не узнаю. Пробовал создавать нового админа, чистить все куки и хранилища, открывать с инкогнито, поведение стабильно одинаковое.

Обсуждение

avatar

wpDiscuz