Про вылет сайтов из индекса из-за Sape
Очень часто встречал и встречаю возгласы — «сайт вылетел из индекса Яндекса из-за сапы!». По началу относился к таким репликам с известной долей скептицизма — мол, либо ВМ слишком жадный — лепит по 100 ссылок на страницу без контента, либо у Яшки глюки.. Так бы и считал до сих пор, если б какое-то время назад сам не столкнулся с глюком Сапы, от которого вполне могли вылететь сайты. Суть глюка — легли оба саповских диспенсера (сервера раздающие ссылки), соответственно скрипт обращался к ним , но ответа не получал и висел так подвесив площадку до истечения таймаута (по умолчанию 6 секунд), но это пол беды, настоящая беда была в том, что фрагмент кода, который разрешал делать повторную попытку обращения к деспенсерам только после определенного времени с момента последней неудачной попытки (по дефолту 600 секунд), на моих сайтах не работал! Таким образом у меня все сайты открывались после «тупежа» в 6 с лишним секунд! Все мы знаем крутой нрав яшко-бота — как думаете, будет он ждать эти 6 секунд?
Взялся разбираться чего не работает код защищающий от постоянного долбления лежащих диспенсеров и… усомнился в целесообразности. Почему? Все очень просто — я представил себе не упавший деспенсер, а глючащий, который время от времени таки что-то отправляет нашему скрипту — как думаете при default_socket_timeout = 6 и отправке диспенсером по 2 байта в 5 секунд скрипт закроет соединение через 6 секунд или нет? Я однозначного ответа на этот вопрос не нашел. А по аналогии с другими таймаутами можно сделать вывод, что скрипт отцепится только если не будет получать вообще никаких данных в течении времени таймаута (наши дефолтные 6 секунд). Или еще веселей — деспенсеры ответят в течении 5 секунд, но вот яшко-бот вряд-ли станет этого дожидаться. Уменьшить таймаут — сайту станет легче, но возможны проблемы с обновлением БД ссылок…
В общем, чтоб не наводить тень на плетень, я решил повесить задачу обновления локальной БД ссылок на крон исключив эту не самую быструю операцию из процесса загрузки страниц.
Что для этого нужно сделать?
Первым делом открываем Ваш файл sape.php и добавляем новое свойство класса SAPE_base. Назовем его _update_local_database .
Итак ищем строку
var $_db_file = ''; //Путь к файлу с данными
И сразу после нее добавляем:
var $_update_local_database = false;
Новое свойство добавлено. Его мы будем использовать для того, чтоб класс знал можно-ли ему обновлять копию БД или нет. Учим класс менять это свойство в зависимости от параметров с какими создаются обьекты. Ищем строки:
if (is_array($options)) {
if (isset($options['host'])) {
$host = $options['host'];
}
сразу после этих строк добавляем строки
if (isset($options['update_local_database'])) {
$this->_update_local_database = $options['update_local_database'];
}
Теперь нужно научить класс обрабатывать это свойство.
Ищем следующий фрагмент кода:
function load_data() {
$this->_db_file = $this->_get_db_file();
Сразу после него добавляем следующую строку:
if( $this->_update_local_database) {
Теперь надо добавить закрывающуюся скобку. Ищем:
break;
}
}
}
}
}
И сразу после этого фрагмента добавляем еще одну закрывающуюся фигурную скобку } .
Нажимаем Ctrl+S затем Alt+F4 :). редактирование Sape.php на этом завершено. После этих модификаций и при штатной установке кода файл links.db никогда не обновится, разумеется если ему не помочь :). Этим мы сейчас и займемся.
Создаем файл с произвольным названием и расширением php , например get_link.php и размещаем его на сайте (для примера в корне). Копируем в него следующий код:
<?php
if (!defined('_SAPE_USER')){
define('_SAPE_USER', 'xxxxxxxxxxxxxxxxxxxxxxxxxx');
}
require_once($_SERVER['DOCUMENT_ROOT'].'/'._SAPE_USER.'/sape.php');
$o['update_local_database'] = true;
$sape = new SAPE_client($o);
$sape_context = new SAPE_context($o);
?>
Заменяем
xxxxxxxxxxxxxxxxxxxxxxxxxx
на свой идентификатор (совпадает с названием папки, в которой лежит sape.php). Все. осталось настроить крон, чтоб он регулярно заходил wget-ом на наш get_link.php . Я использую такую строку:
wget -q http://site.ru/get_link.php
Что делать если сайтов много? Ставить много заданий для крона — обидится хостер. Делаем проще — на одном из сайтов , для примера site5.ru создаем в корне файлик ping.php. Копируем в него следующий код:
<?php
file_get_contents('http://site1.ru/get_link.php');
file_get_contents('http://site2.ru/get_link.php');
file_get_contents('http://site3.ru/get_link.php');
file_get_contents('http://site4.ru/get_link.php');
file_get_contents('http://site5.ru/get_link.php');
?>
Замечу, что добавлять в этот список больше 5-6 сайтов следует очень осторожно т.к. у многих хостеров стоит ограничение на время исполнения скрипта 30 секунд.
Правим имена сайтов и названия файлов на свои и прописываем в кроне дерганье уже этого скрипта:
wget -q http://site5.ru/ping.php
Все!
Процесс загрузки страниц Вашего сайта абсолютно не зависим от состояния сапе-диспенсеров, при этом БД ссылок регулярно обновляется.
Понравилась информация? А мои «активные рефы»: уже пользуются ею, да и не только ею :). Намек понятен?