1

我们有 10,000 个博客,我们希望每天多次查看新帖子。我喜欢一些关于使用 Perl 最有效的方法的示例代码的想法。

目前,我们只是使用LWP::UserAgent下载每个 RSS 提要,然后将生成的提要中的每个 URL 与已找到的 URL 的 MySQL 数据库表逐个检查一个。不用说,这不能很好地扩展并且效率非常低。

提前感谢您的帮助和建议!

4

4 回答 4

3

不幸的是,除了进行某种轮询之外,可能别无他法。

幸运的是,实现PubSubHubbub 协议可以极大地帮助减少支持它的提要的轮询量。

对于那些不支持 PubSubHubbub 的提要,您必须确保使用 HTTP 级别的协议(例如ETagsIf-Modified-Since标头以了解资源是否/何时更新)。还要确保您实施某种退避机制。

于 2010-12-12T23:47:55.237 回答
2

也许看看AnyEvent::Feed,它是异步的(使用 AnyEvent 事件循环),具有可配置的轮询间隔,并且内置支持“已见”文章,并支持 RSS 和 Atom 提要。您可以创建一个轮询每个提要的单个进程或多个轮询提要列表的不同部分的进程。

来自简介:

      use AnyEvent;
      use AnyEvent::Feed;

      my $feed_reader =
         AnyEvent::Feed->new (
            url      => 'http://example.com/atom.xml',
            interval => $seconds,

            on_fetch => sub {
               my ($feed_reader, $new_entries, $feed, $error) = @_;

               if (defined $error) {
                  warn "ERROR: $error\n";
                  return;
               }
               for (@$new_entries) {
                     my ($hash, $entry) = @_;
                     # $hash a unique hash describing the $entry
                     # $entry is the XML::Feed::Entry object of the new entries
                     # since the last fetch.
               }

            }
         );
于 2010-12-13T01:04:58.947 回答
0

似乎两个问题合二为一:获取比较。其他人已经回答了获取部分。至于比较:

  • 我最近一直在阅读有关redis的文章,它似乎很适合您,因为它每秒可以执行很多简单的操作(比如说 ~80k /s)。所以检查你是否已经有一个 url 应该很快。虽然从未真正使用过它;)

  • 一个想法:您是否尝试过在解析 RSS 之前比较大小?如果不经常更改,可能会为您节省一些时间。

于 2010-12-13T10:28:16.363 回答
0

10000不是那么多。

您可能可以使用一些简单的方法来处理,例如分叉一些从数据库获取 RSS URL 的工作进程,获取它们并更新数据库:

for (1..$n) {
  my $pid = fork;
  if (!$pid) {
     defined $pid or die "fork failed";
     my $db = open_db();
     while (1) {
       $url = get_next_url($db) or last;
       $rss = feed_rss($url);
       update_rss($db, $rss);
     }
     exit(0);
  }
}
wait_for_workers(@pid);

考虑到您无法使用其他响应者已经指出的一些现有应用程序。

于 2010-12-13T11:15:23.963 回答