Сегодня утром один из моих клиентов написал что всю ночь сайт не отвечает, а сейчас открывается по 20 секунд. Идем разбираться - с местом на сервер все в порядке, с настройками тоже, но загрузка всех ядер 100% и не думает падать. В логах очень много хитов, прямо таки аномально много, сайт не такой популярный) В итоге в логах вижу строчки огромной боли многих веб-мастеров - UserAgent: YandexBot 3.0.
Бот прямо таки ненасытен - генерирует по 20-30 хитов в секунду. ЧТобы проверить действительно ли он "виновник происшествия" - блокирую в nginx все подключения с UserAget YandexBot.
Для этого в блоке server конфигурации nginx прописываю:
Нагрузка через некоторое время спадает, яндекс вебмастер начинает "плеваться" ошибками индексации в почту. Устанавливаю в панели Яндекс Вебмастер параметр "" на 1 запрос в секунду. УБираю блок в nginx.
Загрузка снова растет до 100%, все ложится.
То есть видимо параметр применится только на следующий обход. Смотрим что еще можно сделать чтобы умерить аппетиты Яндекса.
На странице нахожу еще одно решение - возвращать на все запросы код HTTP код 429. Прописываю в ini.php:
http_response_code(429);
Жду пару минут. Нагрузка спадает до нормальных значений. Но возвращать на каждый хит 429 как-то не правильно. То есть возвращать нам его нужно только когда высокая загрузка системы и возвращать только поисковым ботам. Реальному посетителю мы должны открыть сайт в любом случае с нормальными ответами. Набросал вот такой код и добавил в init.php:
Для определения мгновенной загрузки использую стандартную функцию sys_getloadavg. Так как на сервер 2 вычислительных ядра, нагрузка больше 2 это уже перегруз, в этом случае ничего не делаем и выдаем ошибку. Если же загрузка более 0.8 - просто выдаем код 429 и контент. В таком варианте работает сейчас. Значения порогов подбираете на вашем железе экспериментально.
Бот прямо таки ненасытен - генерирует по 20-30 хитов в секунду. ЧТобы проверить действительно ли он "виновник происшествия" - блокирую в nginx все подключения с UserAget YandexBot.
Для этого в блоке server конфигурации nginx прописываю:
if ($http_user_agent ~* (YandexBot)) {
return 403;
} |
Загрузка снова растет до 100%, все ложится.
То есть видимо параметр применится только на следующий обход. Смотрим что еще можно сделать чтобы умерить аппетиты Яндекса.
На странице нахожу еще одно решение - возвращать на все запросы код HTTP код 429. Прописываю в ini.php:
http_response_code(429);
Жду пару минут. Нагрузка спадает до нормальных значений. Но возвращать на каждый хит 429 как-то не правильно. То есть возвращать нам его нужно только когда высокая загрузка системы и возвращать только поисковым ботам. Реальному посетителю мы должны открыть сайт в любом случае с нормальными ответами. Набросал вот такой код и добавил в init.php:
if (!empty($_SERVER['HTTP_USER_AGENT'])) {
$options = array(
'YandexBot', 'YandexAccessibilityBot', 'YandexMobileBot','YandexDirectDyn',
'YandexScreenshotBot', 'YandexImages', 'YandexVideo', 'YandexVideoParser',
'YandexMedia', 'YandexBlogs', 'YandexFavicons', 'YandexWebmaster',
'YandexPagechecker', 'YandexImageResizer','YandexAdNet', 'YandexDirect',
'YaDirectFetcher', 'YandexCalendar', 'YandexSitelinks', 'YandexMetrika',
'YandexNews', 'YandexNewslinks', 'YandexCatalog', 'YandexAntivirus',
'YandexMarket', 'YandexVertis', 'YandexForDomain', 'YandexSpravBot',
'YandexSearchShop', 'YandexMedianaBot', 'YandexOntoDB', 'YandexOntoDBAPI',
'Googlebot', 'Googlebot-Image', 'Mediapartners-Google', 'AdsBot-Google',
'Mail.RU_Bot', 'bingbot', 'Accoona', 'ia_archiver', 'Ask Jeeves',
'OmniExplorer_Bot', 'W3C_Validator', 'WebAlta', 'YahooFeedSeeker', 'Yahoo!',
'Ezooms', '', 'Tourlentabot', 'MJ12bot', 'AhrefsBot', 'SearchBot', 'SiteStatus',
'Nigma.ru', 'Baiduspider', 'Statsbot', 'SISTRIX', 'AcoonBot', 'findlinks',
'proximic', 'OpenindexSpider','statdom.ru', 'Exabot', 'Spider', 'SeznamBot',
'oBot', 'C-T bot', 'Updownerbot', 'Snoopy', 'heritrix', 'Yeti',
'DomainVader', 'DCPbot', 'PaperLiBot'
);
foreach($options as $row) {
if (stripos($_SERVER['HTTP_USER_AGENT'], $row) !== false) {
$load = sys_getloadavg();
if ($load[0] > 2) {
header('HTTP/1.1 429 Too many requests');
die('Server too busy. Please try again later.');
}
if ($load[0] > 0.80) {
http_response_code(429);
}
}
}
} |