在App Engine上优化RSS解析以避免高CPU警告
我正在把一些RSS源拉到App Engine的数据库里,以便给iPhone应用提供服务。我用定时任务每隔一段时间更新一次RSS。每个任务只解析一个RSS源(这个源大约有15到20个项目)。我经常在App Engine的仪表盘上看到高CPU使用率的警告,所以我在寻找优化代码的方法。
目前,我使用的是minidom(因为它已经在App Engine上可用了),但我怀疑它的效率不是很好!
这是我的代码:
dom = minidom.parseString(urlfetch.fetch(url).content)
if dom:
items = []
for node in dom.getElementsByTagName('item'):
item = RssItem(
key_name = self.getText(node.getElementsByTagName('guid')[0].childNodes),
title = self.getText(node.getElementsByTagName('title')[0].childNodes),
description = self.getText(node.getElementsByTagName('description')[0].childNodes),
modified = datetime.now(),
link = self.getText(node.getElementsByTagName('link')[0].childNodes),
categories = [self.getText(category.childNodes) for category in node.getElementsByTagName('category')]
);
items.append(item);
db.put(items);
def getText(self, nodelist):
rc = ''
for node in nodelist:
if node.nodeType == node.TEXT_NODE:
rc = rc + node.data
return rc
其实代码里没什么复杂的东西,但这些脚本经常需要2到6秒的CPU时间,这对于处理大约20个项目和读取几个属性来说,似乎有点过长。
我该怎么做才能让这个过程更快呢?上面的代码有什么特别不好的地方吗?还是说我应该换一种解析方式?有没有什么更好的库(能在App Engine上用)?或者我自己解析RSS会更好?
5 个回答
如果你的网站访问量很少,你可能会遇到应用启动时间的问题。当一个应用闲置几分钟后,应用引擎会为了节省资源而将你的应用关闭。等到下一个请求到来时,应用就得重新启动才能处理这个请求,而这个过程会消耗你的CPU配额。如果你去搜索应用引擎的讨论组,你会发现里面充满了关于这个问题的抱怨。
我在我的网站 www.newsfacet.com 使用了superfeedr,我注意到当superfeedr给我发通知时,大多数情况下我能在几百毫秒内处理几个RSS文章。但如果上次输入已经过去了一段时间,这个处理时间可能会跳到10秒或11秒,因为这时候就要承担重新启动的成本。
关于使用PubSubHubbub让别人帮你处理事情,你可以看看我写的这篇关于在App Engine上使用hubbub的博客文章,可能会对你有帮助。
通过例如superfeedr外包提要解析
你可以看看 superfeedr.com。他们提供合理的免费配额和付费计划。他们会为你定期检查更新(大约每15分钟就能收到更新)等。如果这些提要还支持 pubsubhubbub,那么你就能实时收到提要!如果你还不太了解 pubsubhubbub,这个视频会给你解释清楚。
Brett Slatkin编写的改进版提要解析器
我还建议你看看这段很棒的 视频,是Brett Slatkin讲解pubsubhubbub的。我记得他在演示中提到,他不使用 Universal Feedparser
,因为这个工具对他的问题来说工作量太大了。他自己写了一个SAX解析器(在视频的14:10处他稍微提到了一下),速度非常快。我想你应该去看看pubsubhubbub的 代码,了解他是怎么做到的。