14 September 2024
Дуже погано, коли сайт падає. Набагато гірше, коли він падає через незрозумілу причину. Іноді на встановлення причини збою може знадобитися тривалий час, якщо весь цей час сайт "лежатиме" адміністратор може просто звільнити. На щастя, є рішення, що дозволяє трохи скрасити "гіркоту падіння" і воно буде описано у цій статті.
Сутність рішення в наступному: потрібно налаштувати/написати самому засіб моніторингу працездатності сайту. Якщо сайт "упав", цей засіб буде перезапускати сервіси 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 хвилин, якщо сайт "лежить" часто - раз на хвилину. Так, це створить додаткове навантаження на сервер, зате забезпечить його перезапуск протягом однієї хвилини.
Напишемо невеликий PHP-сценарій, що підключається до БД і повертає 1, якщо з'єднання вдалося і 0, якщо з'єднання не працює. Власне код цього сценарію дуже простий:
include "config.php"; // тут параметри доступу до БД $mysqli = new mysqli($DBHOST, $DBUSER, $DBPASSWD, $DBNAME); if ($ mysqli->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 не напишеш. Натомість наведу реальний конфіг моніторингу 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%, сервіс перезапускався і якщо сервер вже впав (не вдається одержати файл), то сервіс також перезапускався.