Приветствую!
Столкнулся с крайне непонятной ситуацией и нуждаюсь в вашей помощи или хотя-бы каких-то предположениях :)
Исходные данные: Жил себе сайт, написанный довольно давно на PHP в стилях «говнокод» и «спагетти», в чем-то неудобный в чем-то устаревший, но рабочий. (Параллельно с функционирование сайта шло, и до сих пор идет его переписывание на популярном фреймворке с использованием годных практик программировани, так что совет «выкинуть и переписать» потихоньку релизуется)
В какой-то момент сайт был перенесён на виртуальный сервер от Selectel, и стал жить там. После более года жизни на сервере, неделю назад начались симптомы болезни: - В основном все работает хорошо - Иногда, примерно каждый 10-й раз, но вообще как повезёт (иногда и 10 раз подряд) случайные страницы грузятся ОЧЕНЬ долго, иногда этот процесс заканчивается успешной загрузкой, но часто - превышается максимальный период выполнения PHP-скрипта и взоваращается пустая страница.
Система: debian squeeze, тип виртуализации неизвестен (но скорее всего что-то типа OpenVZ) - буду благодарен если подскажете как изнутри виртуалки проверить тип виртуального сервера.
Сервер: apache2, php5.3 конкретные версии не особо важны, далее объясню почему.
Что было предпринято: (извиняюсь за долгое расписывание, просто хочу чтобы сразу отпало много вопросов)
0) Нагрузочное тестирование через Apache Benchmark при определенном количестве запросов (например, 50 в секунду) приводило к тому что максимальное время запроса становилось как раз 60 секунд, и большая часть запросов не была обработана (по результатам ab)
1) Мониторинг нагрузки: во время таких «зависаний» top и htop показывали что система не особо то и загружена. 10% CPU, 40% RAM
2) Мониторинг SQL: long queries log в mysql были включены, и показали что за полдня таких запросов набарлось 2 штуки, по 2 секунды каждый.
3) Мониторинг подключений к SQL: их всего штук 10-20 набиралось от силы, с учетом ожидающих
4) Полное обновление системы (ПО не обновлялось уже год наверное) - ничего не изменилось
5) Установка apache и php из DotDeb - ничего не изменилось
6) Установка nginx + php5-fpm, настройка их на 81-м порту (для проверки) - опять же ничего не изменилось, под nginx конечно все стало работать чуть побыстрее, но тормозные страницы так и открывались тормозно! Вывод - дело не в апаче и пхп, и не в их версии,а в чем-то другом.
7) Оптимизация работы с базой путём добавления memcache - с помощью XDEBUG_PROFILE посмотрел все узкие места работы с базой, и добавил туда кэширование (где было допустимо). Страницы стали грузиться со скоростью света! Но те, которым выпадала судьба тормозить - тормозили как и раньше по 30-60 секунд.
8) Поставил xdebug_profile в ВЕЧНО-Включенное состояние, и стал анализировать самые жирные логи. И вот что выяснилось: На тех страницах, которые случайным образом начинали тормозить большую часть времени занимали файловые операции. А конкретно:
file_get_contents - считывающий файл с диска а не откуда-то из интернета по 20-60 секунд (упирается в max_execution_time)
include, require, require_once - да, по 25 секунд на каждый! А иногда и по 60!
session_start() - тоже от 20 до 60 секунд.
На счёт session_start() знаю, что можно перенести их в БД или в Мемкэш или ещё куда, и проблема решится, но зато не решатся остальные проблемы с файлами. И никаких «одновременных запросов» к сессии одного юзера не производится. На сайте нет никакого аякса, никаких фоновых работ, просто странички сгенерированные PHP.
Вся эта ситуация выглядит так, как будто доступ к файлам блокируется разными процессами, т.е. один получил доступ, другой его ждет.
9) Последнее что я предпринял - это попытался посмотреть количество доступных файловых дескрипторов (дескрипторов открытых файлов), через
# cat /proc/sys/fs/file-nr
Результат:
1376 0 6592120
то есть, как я понял, всего у меня есть 6.5 миллионов а из них использовано 1376.
Я знаю о том, что на некоторых системах пара-виртуализации можно «насильно» ограничивать какие-то параметры гостевой системы, поэтому решил проверить, каким вообще бывает это число занятых дескрипторов. Снова запустил apache benchmark, и стал с помощью watch смотреть на это число. Больше чем до 1440 оно так и не поднялось!
Последняя догадка в том что админы Selectel снизили количество открываемых файлов до такого количества (а может это админ данного сервера - если там не OpenVZ как-то умудрился это сделать), но для проверки этого у меня к сожалению не хватает опыта и знаний. (Тикет в Селектел я написал но ответа нет.)
Также, к сожалению не удалось воспользоваться утилитой iotop, которая должна показывать нагрузку дисковых операций.
Её выдача: «OSError: Netlink error: No such file or directory (2)», на просторах гугла нашел, что это значит, что, скорее всего у меня именно паравиртуализация которая не даёт делать некоторые вещи с ФС и ядром.
Может среди благородных донов на LORе найдется кто-то с подобным жизненным опытом...
Заранее спасибо за то что думали в направлении моего вопроса :)