Карта сайта для поисковиков (Sitemap) в Zend Framework приложении

// Август 24th, 2011 // SEO, Zend Framework

По работе занимаюсь созданием довольно большого портала. Не люблю я это слово, но оно наиболее полно отражает суть веб-сервиса. На этой неделе встала задача генерации sitemap файла для поисковиков. Всё бы ничего но по примерным подсчётам на сайте никак не меньше 3 000 000 страниц, которые надо скормить роботу. Ввиду такого количества поисковик просто не индексирует их все, упираясь в свой лимит. Собственно поэтому и нужен sitemap.

Задача

Создать карту сайта(sitemap.xml/sitemap.txt) для большого сайта на Zend Farmework.

Решение

Необходимо создать список публично доступных-страниц сайта, т.е. ссылок на них. Ссылки в нормальном ZF-приложении генерятся через Url Helper:

url($urlOptions, $name, $reset): Creates a URL string based on a named route. $urlOptions should be an associative array of key/value pairs used by the particular route.

А значит у нас есть единая точка генерации ссылок. Это позволит нам составить список ссылок для карты сайта.

Нашей первой идеей было пробежаться по всем маршрутам (по которым url хелпер строит ссылки) и сгенерить ссылкы на основе маршрутов и данных из БД. Это оказалось плохой затеей, т.к. данных в базе было много, ссылок тоже и время генерации карты сайта выходило за все разумные пределы.

Второй идеей было перехватывать вызовы url-хелпера и журналировать их в БД, а потом уже на основе журнала генерировать sitemap. Т.е. сделать БД буфером между запросами хелпера и файлом sitemap. У этой идеи был свои недостатки. На каждую ссылку на странице делалось два запроса к БД: один на чтение из таблицы sitemap (а была ли уже такая ссылка) и второй на запись (создание новой записи или обновленеи времени доступа существующей). Если на странице 80 ссылок, то имеем + 160 запросов к БД. Не вариант.

Тогда на ум пришла третья идея. А что если буферизировать вызовы хелпера в приложении. Т.е. по ходу генерации страницы собираем в массив все ссылки, а потом… нет, не пишем в БД, ведь тогда надо опять же проверять существование ссылок… отправляем задачу на сервер очередей.

Солюшен

  1. Журналируем вызовы url-хелпера и складываем их в массив в локальной переменной.
  2. Перед отдачей результатов рендеринга страницы пользователю отправляем задание с этим массивом  в очередь.
  3. Отдаем страницу.
  4. Демон очереди получает задачу и в фоновом режиме (может даже на отдельном сервере) и осуществляет чтение/запись в БД.
  5. Где-нибудь ночью запускается cron-скрипт, который на основе подготовленных демоном данных в БД генерирует карту сайта.ъ
  6. PROFIT! :-)

Преимущества

  • Нет оверхеда при генерации страницы, только быстрая отправка задания в очередь.
  • Актуальность карты сайта = период запуска крон скрипта.
  • Потенциально неограниченный размер карты сайта, за счёт разделения работы между подсистемами и фоновой генерацией карты.

Недостатки

  • Нужен сервер очередей :-)
  • Все ссылки на сайте должны генерироваться через URL хелпер.

На самом деле в нормальном проекте всё так и есть. Если нет, это повод задуматься. Думаю эта заметка будет полезной для ZF разработчиков.

Токарчук Андрей

Share

Спасибо!


Если вам помогла статья, или вы хотите поддержать мои исследования и блог - вот лучший способ сделать это:


7 Responses to “Карта сайта для поисковиков (Sitemap) в Zend Framework приложении”

  1. abc:

    А если кто-то будет соваться на несуществующие страницы? Например робот (спамер, ищейка уязвимостей… ) или просто страница удалена, а люди все равно на нее прут

    • google.com Андрей Токарчук:

      Выдавать 404 код, чтобы страница исчезла из индекса поисковика. Ищейки пусть прут, будут часто заходить, можно начать их банить.

  2. Oleg:

    Сейчас решаю подобную задачу.
    Возникает вопрос — а как быть с ссылками, которые роботу не надо видеть?
    Типа /post/edit или /admin, ну и ссылки, которые доступны только авторизованным пользователям (личная почта) ?

    • google.com Андрей Токарчук:

      Ну тут два варианта, либо сравнивать с массивом из черного списка, либо запретить в robots.txt

      • Oleg:

        Сделал по другому :)
        Ставить в очередь герману только тогда, когда ссылки генерируются для неавторизованного пользователя.

        • Oleg:

          Другими словами, если по сайту бродит кто-то неавторизованный — то ссылки добавляем серверу очередей для обработки.

Комментировать