Поднимаем сайт: "неотложка" пока спит админ


Очень плохо, когда сайт падает. Гораздо хуже, когда он падает по непонятной причине. Иногда на установление причины сбоя может понадобиться продолжительное время, если все это время сайт будет "лежать" админа могут просто уволить. К счастью, есть решение, позволяющее немного скрасить "горечь падения" и оно будет описано в этой статье.

Не панацея, а костыль

Автор этой статьи на своей практике столкнулся с нестабильной работой сайта (виртуальный Linux-сервер, CMS Magento). Причем полгода сайт работал как швейцарские часы, а затем начались непонятные падения.

Суть решения в следующем: нужно настроить/написать самому средство мониторинга работоспособности сайта. Если сайт "упал", это средство будет перезапускать сервисы Apache и MySQL (или только Apache – все зависит от специфики сайта и причины сбоя).

Решение, конечно же, временное. Нужно найти и устранить причину падения, но зато такой "костыль" позволяет быстро восстановить работоспособность сайта: руководство даже не заметит сбой. Что же касается обычных пользователей, то даже если кто-то и получит 550-ую ошибку, а через минуту сайт уже будет работать, вряд ли кто-то будет особо жаловаться.

Проверять работоспособность сайта можно двумя способами: или пытаться получить реальный файл (можно для этого создать пустой файл в корне, важно получить 200-ый ответ от сервера) или же мониторить наличие сервисов apache/mysql в памяти. Второй способ не защищает от ситуации, когда сервисы "подвисли" – в памяти они есть, но на самом деле сайт "лежит". Первый способ не позволяет убедиться в работоспособности MySQL: файл веб-сервер может и "отдать", а база данных может не работать.

Проверка работоспособности веб-сервера

Проще всего проверить работоспособность веб-сервера путем обращения к его главной странице: если получен ответ 200, значит с сервером все хорошо. Bash-сценарий будет выглядеть так:

#!/bin/bash

if curl -s --head --request GET https://site.name | grep "200 OK" > /dev/null; then
  echo "Site is UP"
else
  echo "site is DOWN, restarting Apache"
  /usr/sbin/service apache2 restart
fi

Вызов сценария нужно поместить в расписание cron. Периодичность зависит от частоты падения сервера – если сервер сбоит иногда, можно раз в 5-10 минут, если сайт "лежит" часто – раз в минуту. Да, это создаст дополнительную нагрузку на сервер, но зато обеспечит его перезапуск в течение одной минуты.

Проверка работоспособности MySQL

Напишем небольшой PHP-сценарий, подключающийся к БД и возвращающий 1, если соединение удалось и 0, если соединение не работает. Собственно, код этого сценария очень прост: connect_errno) { echo "0"; } else "1"; // connect ok ?>

Затем создается bash-сценарий подобный этому: #!/bin/bash RESULT=$(/usr/bin/php test-mysql.php) if [ $RESULT –eq 0 ]; then echo "Restarting MySQL" /etc/init.d/mysqld restart fi

Как и в случае с первым нашим bash-сценарием, вызов этого сценария нужно поместить в расписание планировщика. Можно объединить эти два bash-сценария в один и вызывать все сразу.

Если падают процессы

Если процессы не виснут, а "падают", то есть после сбоя вообще нет процессов Apache/MySQL в таблице процессов, тогда поможет следующий сценарий:

#!/bin/bash
RESTART="/etc/init.d/apache2 restart"
PGREP="/usr/bin/pgrep"
HTTPD="apache2"
$PGREP ${HTTPD}
if [ $? -ne 0 ]; then
$RESTART
date >> /var/log/srvmon.log
echo "Apache restarted" >> /var/log/srvmon.log
fi

RESTARTM="/etc/init.d/mysql restart"
MYSQLD="mysqld"
$PGREP ${MYSQLD}
if [ $? -ne 0 ]; then
$RESTART
$RESTARTM
date >> /var/log/srvmon.log
echo "Services restarted" > /var/log/srvmon.log
fi

Он не только перезапускает "упавшие" сервисы, но и ведет небольшой лог – записывает время, когда сервисы были перезапущены.

Monit: если нет таланта программиста

Все приведенное ранее можно сделать и с помощью сервиса monit. Его задача – мониторинг работоспособности сервера. Если что-то не так, то monit может перезапустить ту или иную службу.

В Интернете есть множество статей, посвященных monit, к тому же у него очень хорошая документация. Поэтому не хочется плагиатить – ничего нового на тему monit уже не напишешь. Вместо этого приведу реальный конфиг мониторинга Apache с одного из администрируемых автором этой статьи серверов:

check process apache with pidfile /var/run/apache2.pid
   group www
   group apache
   start program = "/etc/init.d/apache2 start"
   stop program  = "/etc/init.d/apache2 stop"
   # если загрузка cpu > 90% 5 циклов то перезапустить процесс.
   if cpu > 90% for 5 cycles then restart    
   # если не удается получить файл server-status, перезапустить
   if failed host localhost port 80 with protocol http and request "/server-status" with timeout 25 seconds for 4 times within 5 cycles then restart
   depend apache_bin
   depend apache_rc

 check file apache_bin with path /usr/sbin/apache2
   group apache
   include /etc/monit/templates/rootbin

 check file apache_rc with path /etc/init.d/apache2
   group apache
   include /etc/monit/templates/rootbin

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