Как стать автором
Обновить

Выживание в моменты критической нагрузки

Время на прочтение2 мин
Количество просмотров2.1K
В жизни каждого посещаемого ресурса случаются моменты, когда оборудование не справляется с текущей нагрузкой. Причины могут быть самыми разнообразными, и не всегда их можно кардинально искоренить в разумное время. В таких случаях перед разработчиками встает задача снизить нагрузку с минимальными неудобствами для посетителей.

Не претендую на гениальность своего решения, но надеюсь, кому-нибудь оно поможет.


В моем случае проблема в том, что время от времени резко поднимается нагрузка на базу данных. Как обычно бывает в таких случаях возникала лавина – запросы начинают тормозить, пользователи нервничают и жмут reload, кроновские скрипты тормозят и в результате сервер «подвисает». Кроме того, поисковые роботы добавляют проблем – они имеют свойство вытягивать глубинные страницы с сайта, которые в обычном режиме в кеше не живут. В результате страницы для них генерируются и кеш заполняется ненужными данными. Со второй частью проблемы можно справиться достаточно легко – просто не кешировать обращения к старым страницам, либо обращения роботов. Но вполне можно пойти дальше и снять нагрузку от роботов хотя бы на время когда сервер перегружен.

Передо мной встало две задачи:

1. Как определить момент возникновения повышенной нагрузки
2. Что можно сделать в эти моменты чтобы жить стало легче

Для решения первой задачи я воспользовался знаменитым чудо-инструментом zabbix, благо он давно, активно и успешно используется и позволяет мониторить несколько серверов, а также выполнять на них команды при возникновении нужных условий. Для своего случая я выбрал load average на сервере базы данных. А реагировать мне нужно на другом сервере, на котором живет nginx.

Я создал триггер с условием system.cpu.load[,avg1].last(0)>3.5, навесил на него выполнение удаленной команды

HOST: /path/lowerage.sh {STATUS} {ITEM.LASTVALUE} {TIME}

А на сервере разместил простенький скриптик:

if [ "${1}" != "ON" ] ; then
/bin/unlink /tmp/cpu_load_high
else
/usr/bin/touch /tmp/cpu_load_high
fi
echo "lowerage ${1} ${2} ${3}" |/usr/bin/mail -s lowerage tmp@tmpmail.ru


В результате в моменты поднятии нагрузки создавался файлик, от которого уже можно плясать дальше.

Плавно переходим собственно к действиям.

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

/bin/test! -r /tmp/cpu_load_high && /usr/bin/fetch -o — site/cron.php

Потом я начал нежно прижимать поисковых роботов. Решил их отсекать во критическое время на уровне nginx. С последним пришлось проявить смекалку, дело в том, что nginx не понимает вложенных if, а мне нужно минимум два условия. Выручил финт ушами. Кусок файла конфигурации, реализующий вышеописанное, привожу ниже:

if (-f /tmp/cpu_load_high) {
set $troubleflag T;
}
if ($http_user_agent ~ (?:Yandex|Google|Yahoo|Rambler|msnbot) ) {
set $oblomflag Y$troubleflag;
}
if ($oblomflag = YT) {
return 444;
}


Кстати, не уверен, что вариант с return 444 оптимален. При этом nginx просто обрывает соединение. Думаю, что роботы не должны сильно обижаться на такое поведение.

Вот собственно и вся недолга. На будущее еще можно в критические времена не обрабатывать какие-то тяжелые запросы – перекидывать пользователя на страницу с извинениями.

Спасибо за внимание.

UPD: в комментах подсказали ссылку googlewebmastercentral.blogspot.com/2006/08/all-about-googlebot.html где гугл рекомендует использовать код 503.
Теги:
Хабы:
Всего голосов 14: ↑14 и ↓0+14
Комментарии11

Публикации

Истории

Работа

Ближайшие события

15 – 16 ноября
IT-конференция Merge Skolkovo
Москва
22 – 24 ноября
Хакатон «AgroCode Hack Genetics'24»
Онлайн
28 ноября
Конференция «TechRec: ITHR CAMPUS»
МоскваОнлайн
25 – 26 апреля
IT-конференция Merge Tatarstan 2025
Казань