Карта сайта для поисковиков (Sitemap) в Zend Framework приложении
По работе занимаюсь созданием довольно большого портала. Не люблю я это слово, но оно наиболее полно отражает суть веб-сервиса. На этой неделе встала задача генерации sitemap файла для поисковиков. Всё бы ничего но по примерным подсчётам на сайте никак не меньше 3 000 000 страниц, которые надо скормить роботу. Ввиду такого количества поисковик просто не индексирует их все, упираясь в свой лимит. Собственно поэтому и нужен sitemap.
Задача
Создать карту сайта(sitemap.xml/sitemap.txt) для большого сайта на Zend Farmework.
Решение
Необходимо создать список публично доступных-страниц сайта, т.е. ссылок на них. Ссылки в нормальном ZF-приложении генерятся через Url Helper:
|
1 |
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 запросов к БД. Не вариант.
Тогда на ум пришла третья идея. А что если буферизировать вызовы хелпера в приложении. Т.е. по ходу генерации страницы собираем в массив все ссылки, а потом… нет, не пишем в БД, ведь тогда надо опять же проверять существование ссылок… отправляем задачу на сервер очередей.
Солюшен
- Журналируем вызовы url-хелпера и складываем их в массив в локальной переменной.
- Перед отдачей результатов рендеринга страницы пользователю отправляем задание с этим массивом в очередь.
- Отдаем страницу.
- Демон очереди получает задачу и в фоновом режиме (может даже на отдельном сервере) и осуществляет чтение/запись в БД.
- Где-нибудь ночью запускается cron-скрипт, который на основе подготовленных демоном данных в БД генерирует карту сайта.ъ
- PROFIT! 🙂
Преимущества
- Нет оверхеда при генерации страницы, только быстрая отправка задания в очередь.
- Актуальность карты сайта = период запуска крон скрипта.
- Потенциально неограниченный размер карты сайта, за счёт разделения работы между подсистемами и фоновой генерацией карты.
Недостатки
- Нужен сервер очередей 🙂
- Все ссылки на сайте должны генерироваться через URL хелпер.
На самом деле в нормальном проекте всё так и есть. Если нет, это повод задуматься. Думаю эта заметка будет полезной для ZF разработчиков.