Во-первых, немного контекста.
У нас есть специально созданное приложение PHP, которое работает под Apache и поддерживает наш веб-сайт.
В настоящее время на нашем веб-сайте наблюдается высокая посещаемость. Вот наша текущая настройка: - 10 веб-серверов Linux за балансировщиком нагрузки (каждый сервер имеет 8 ЦП, 30 ГБ ОЗУ) - 1 сервер базы данных Linux MySQL (30 ЦП, 120 ГБ ОЗУ)
Трафик держится нормально большую часть времени, но иногда по неясным причинам мы видим всплеск общего количества активных соединений mysql. Он продолжает утечку, пока не достигнет максимума и в конечном итоге приведет к невозможности использования приложения нашими веб-пользователями.
Когда это происходит, с точки зрения средней нагрузки, памяти, использования ЦП, подкачки диска все серверы в порядке. У них есть много доступных ресурсов.
Мы заметили, что есть много процессов Apache с состоянием соединения CLOSE_WAIT. Мы видели около 600 процессов в этом состоянии на одном из наших веб-серверов.
Кажется, это симптом проблемы, с которой мы сталкиваемся. Однако нам трудно копать глубже. Вот мои вопросы:
Заранее спасибо за помощь,
Я думаю, у вас есть запрос, который блокирует таблицу / некоторые строки, которые другие соединения mysql пытаются обновить дольше, чем следовало бы. Когда это происходит, все входящие запросы складываются позади него, пока вы не достигнете максимального количества подключений.
То же самое происходит на стороне Apache из-за того, что запросы поступают, но не получают ответа (из-за того, что запросы блокируются в базе данных). PHP имеет открытое соединение с базой данных; он сделал запрос и еще не получил ответа. «Зависание» Apache в этот момент - это то, чего вы ожидаете, поскольку он ждет ответа.
Кажется, что Apache зависает извне (ваш браузер / мобильное приложение и т. Д.), Потому что все дочерние элементы, доступные на всех ваших серверах, застревают в ожидании ответа от базы данных. Буквально больше нет доступных подключений. (Это также может быть ограничение на количество подключений, установленное на вашем балансировщике нагрузки). Если вы еще этого не сделали, начните регистрировать изменения состояния на балансировщике нагрузки. Скорее всего, вы увидите, как каждый из ваших веб-серверов многократно поднимается и отключается, пока возникает проблема «грохочущего стада» (объясненная позже).
Я считаю, что ваши связи в CLOSE_WAIT - это симптом, а не проблема. Я бы не стал тратить время на поиск и устранение неисправностей под этим углом, пока не позаботился о более очевидных возможных проблемах (база данных). Скорее всего, как только вы исправите, ваше огромное количество CLOSE_WAIT исчезнет.
Чтобы начать устранение неполадок на стороне базы данных, вы должны включить журнал медленных запросов если вы еще этого не сделали. Пусть он записывает запросы в течение 1 секунды или около того, чтобы посмотреть, что обнаруживается при возникновении проблемы.
Примечание. Журнал медленных запросов не будет записывать запрос, пока запрос не будет завершен. Не думайте, что первый запрос, который появляется при возникновении проблемы, - это проблемный запрос. Может быть, а может и не быть.
Теперь вы можете ожидать, что веб-сайт вернется в нормальное состояние после завершения проблемного запроса, блокирующего другие запросы ...
Не так. Если у вас регулярно поступает 500 запросов в секунду и вы можете обрабатывать, скажем, 1000 запросов в секунду, и ваш запрос блокирует базу данных на 10 секунд. В настоящее время ожидается обработка 5000 запросов в секунду в дополнение к 500 запросам в секунду, которые все еще поступают. Это известно как Проблема грохочущего стада.
Ваша проблема могла быть в чем-то совершенно другом, но это те же самые симптомы проблемы, с которой я имел дело много раз, и в большинстве этих случаев проблема заключалась в том, что запрос к базе данных блокирует другие запросы. Единственный раз, когда я столкнулся с этой проблемой, не связанной с базой данных, был на CentOS (у RHEL тоже есть проблема) 6. К сожалению, у Red Hat есть статья базы знаний, в которой обсуждается эта проблема, доступная только для подписчиков, но есть и другие ссылки. вокруг, если вы их ищете. Если вы думаете, что это может быть так, проверить это невероятно легко. Вам просто нужно добавьте одну строку в свой resolv.conf.
Если проблема появляется в то же / почти в то же время дня, когда это происходит, вам следует проверить свои задания cron (или что-то еще, выполняемое по заданному расписанию), чтобы узнать, отправляется ли проблемный запрос из этого .
Наконец, если вы все же определите, что вас укусила проблема громового стада, я бы предложил установить ограничения для вашего балансировщика нагрузки. Вы должны протестировать сервер, чтобы приблизительно определить максимальное количество запросов, которые он может обрабатывать одновременно, и ограничить балансировщик нагрузки превышение этого количества подключений к каждому внутреннему веб-серверу.
Удачи.