11.5 创建自定义监控命令
如果想监控多台Scrapyd服务器的爬虫进程,则需要手动执行。这是一个很好的机会,能够让我们练习到目前为止所见到的一切知识,创建一个原始的Scrapy命令——scrappy monitor,用于监控一组Scrapyd服务器。我们将该文件命名为monitor.py,并且在settings.py文件中添加COMMANDS_MODULE = 'properties.monitor'。通过快速浏览Scrapyd的文档,我们发现listjobs.json这个API可以为我们提供任务相关的信息。如果想要找到给定目标的基础URL,可以猜到它一定在scrapyd-deploy代码中的某个地方,从而可以让我们在单个文件中找到它。如果查看https://github.com/scrapy/scrapyd-client/blob/master/scrapyd-client/scrapyd-deploy,很快就会发现_get_target()函数(由于其实现没有添加太多值,因此我会忽略它),在该函数中将会给我们提供目标名称及其基础URL。太棒了!我们开始实现该命令的第一部分吧,其代码如下所示。
class Command(ScrapyCommand): requires_project = True def run(self, args, opts): self._to_monitor = {} for name, target in self._get_targets().iteritems(): if name in args: project = self.settings.get('BOT_NAME') url = target['url'] + "listjobs.json?project=" + project self._to_monitor[name] = url l = task.LoopingCall(self._monitor) l.start(5) # call every 5 seconds reactor.run()
目前我们所看到的实现还是很简单的。它使用目标名称和我们想要监控的API地址填充_to_monitor字典。然后,我们使用task.LoopingCall()计划到_monitor()方法的定期调用。_monitor()方法使用了treq和延迟操作,而我们使用了@defer.inlineCallbacks来简化其实现。下面是其代码(已忽略一些错误处理和装饰)。
@defer.inlineCallbacks def _monitor(self): all_deferreds = [] for name, url in self._to_monitor.iteritems(): d = treq.get(url, timeout=5, persistent=False) d.addBoth(lambda resp, name: (name, resp), name) all_deferreds.append(d) all_resp = yield defer.DeferredList(all_deferreds) for (success, (name, resp)) in all_resp: json_resp = yield resp.json() print "%-20s running: %d, finished: %d, pending: %d" % (name, len(json_resp['running']), len(json_resp['finished']), len(json_resp['pending']))
上面这些行已经包含了我们知道的几乎所有Twisted技术。我们使用treq调用Scrapyd的API,并且使用defer.DeferredList立即处理所有响应。当我们的所有结果进入到all_resp之后,则开始迭代并获取其JSON对象。treq Response的json()方法将会返回延迟操作,而不是真实值,我们对其执行了yield操作,并会在未来的某个时间点恢复其真实值。最后一步,我们打印出结果。JSON响应包含待处理、运行中及已完成任务列表的信息,我们将打印出它们的长度。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论