Несколько RSS-каналов с PHP (производительность)

В моем недавнем проекте я работаю с несколькими RSS-каналами. Я хочу перечислить только последние сообщения из всех и отсортировать их по отметкам времени.

Моя проблема в том, что у меня около 20 разных фидов, а страница загружается 6 секунд (только тестирование с 10 фидами).

Что я могу сделать, чтобы сделать его лучше?

Я использую симплексмл:

simplexml_load_file($url);

Который я добавляю в массив:

function appendToArray($key, $value){
$this->array[$key] = $value;
}

Непосредственно перед показом я делаю krsort:

krsort($this->array);

Должен ли я кэшировать это как-то?


person Jafu    schedule 13.08.2010    source источник


Ответы (4)


Вы делали какую-либо отладку? Регистрация microtime в различных точках вашего кода.

Вы обнаружите, что загрузка RSS-канала, а не его синтаксический анализ, требует времени, но вы можете обнаружить, что это связано со временем, которое требуется для создания каждого RSS-канала.

Сохраните эти десять фидов в виде статических xml-файлов, наведите на них скрипт и посмотрите, как быстро они загружаются.

person Adam Hopkinson    schedule 13.08.2010
comment
Это была именно моя мысль, но тогда мне нужно, чтобы какой-нибудь cronscript загружался каждые 30 секунд, сохраняя файлы xml. Дело в том, что я буду показывать пользователям последние записи по мере их добавления. - person Jafu; 13.08.2010
comment
Иногда приходится идти на уступки, чтобы соответствовать имеющимся ресурсам. - person Adam Hopkinson; 13.08.2010
comment
Спасибо за ваш вклад. Я буду использовать статические xml-файлы. - person Jafu; 13.08.2010

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

У вас может быть PHP-скрипт, который работает в фоновом режиме (например, через задание cron) и периодически загружает каналы, на которые вы подписаны, в базу данных, тогда вы можете гораздо быстрее получать/фильтровать данные, когда хотите их отобразить.

person Tom Haigh    schedule 13.08.2010
comment
Кажется, это лучшая идея, также см. мой комментарий к Адаму в его ответе :), но все равно спасибо! - person Jafu; 13.08.2010

Вы можете загружать RSS-каналы параллельно с curl_multi. Это может ускорить работу вашего скрипта, особенно если вы сейчас используете блокировку вызовов.

Небольшой пример (из http://www.rustyrazorblade.com/2008/02/curl_multi_exec/ ):

$nodes = array('http://www.google.com', 'http://www.microsoft.com', 'http://www.rustyrazorblade.com');
$node_count = count($nodes);

$curl_arr = array();
$master = curl_multi_init();

for($i = 0; $i < $node_count; $i++)
{
    $url =$nodes[$i];
    $curl_arr[$i] = curl_init($url);
    curl_setopt($curl_arr[$i], CURLOPT_RETURNTRANSFER, true);
    curl_multi_add_handle($master, $curl_arr[$i]);
}

do {
    curl_multi_exec($master,$running);
} while($running > 0);

echo "results: ";
for($i = 0; $i < $node_count; $i++)
{
    $results = curl_multi_getcontent  ( $curl_arr[$i]  );
    echo( $i . "\n" . $results . "\n");
}
echo 'done';

Дополнительную информацию можно найти по адресу Асинхронные/параллельные HTTP-запросы с использованием PHP multi_curl и Как использовать curl_multi() без блокировки (среди прочего).

Кстати, для обработки каналов после их загрузки с помощью curl_multi вам придется использовать simplexml_load_string вместо simplexml_load_file, конечно.

person wimvds    schedule 13.08.2010
comment
Хороший вопрос, но не думаете ли вы, что было бы лучше сохранить файлы, как предлагают другие? - person Jafu; 13.08.2010
comment
Если вы кешируете их, то время от времени у вас будут промахи кеша, если вы не кешируете, то ваш скрипт всегда будет попадать на удаленные серверы (и у вас всегда будет - пусть небольшая - задержка). Лично я бы извлекал их параллельно и кешировал в течение ограниченного времени (которое зависит от частоты обновлений каналов и количества пользователей на вашем сайте, просто посмотрите, что работает для вас). Период кэширования также может быть разным для каждого канала, если это необходимо (например, если вы знаете, что некоторые из них имеют более регулярные обновления, чем другие). - person wimvds; 13.08.2010
comment
Кстати, кэширование само по себе не решит вашу проблему, как уже указывал @Tom Haigh. - person wimvds; 13.08.2010

да, конечно, кэширование — единственное разумное решение.
лучше настроить задание cron для извлечения этих каналов и локального хранения данных.

person Your Common Sense    schedule 13.08.2010