6

至少在我的具体情况下。此处不作一般性陈述。

我有这个用 Node.js 编写的网络爬虫。我很想改用 Ruby,所以我在 EventMachine 中重新编写了它。由于原始版本是在 CoffeeScript 中,它实际上非常简单,而且代码非常相似,除了在 EventMachine 中我实际上可以捕获异常并从异常中恢复(因为我使用的是 Fiber)。

问题在于,在 Node.js 代码上运行不到 20 秒的测试在 EventMachine 上运行时间长达 5 分钟或超过 5 分钟。当我观察连接计数时,它们几乎看起来甚至没有并行运行(它们排队成数百个,然后非常缓慢地向下工作),尽管日志记录显示代码点并行命中的。

我意识到没有代码你不能真正知道到底发生了什么,但我只是想知道是否存在某种潜在的差异,我应该放弃,或者他们是否真的应该能够以同样快的速度运行(a小幅减速很好),我应该继续努力找出问题所在。

我做了以下,但它似乎并没有真正产生任何影响:

puts "Running with ulimit: " + EM.set_descriptor_table_size(60000).to_s
EM.set_effective_user('nobody')
EM.kqueue

哦,我确定我在 EventMachine 中没有任何阻塞调用。我已经对每一行进行了大约 10 次梳理,寻找任何可能阻塞的内容。我所有的网络调用都是 EM::HttpRequest。

4

1 回答 1

13

问题在于,在 Node.js 代码上运行不到 20 秒的测试在 EventMachine 上运行时间长达 5 分钟或超过 5 分钟。当我观察连接计数时,它们几乎看起来甚至没有并行运行(它们排队成数百个,然后非常缓慢地向下工作),尽管日志记录显示代码点是并行命中的。

如果它们没有并行运行,那么它就不是异步的。所以你在阻止。

基本上,您需要弄清楚您在标准 Ruby 库中进行了哪些阻塞 IO 调用,然后将其删除并替换为 EventMachine 非阻塞 IO 调用。

您的代码可能没有任何阻塞调用,但您使用的不是您自己的或不是来自的第 3 方代码EM?他们可能会阻止。即使是像调试打印/日志这样简单的东西也可能会阻塞。

我所有的网络调用都是 EM::HttpRequest。

文件 IO 呢, TCP 呢?其他可以阻止的东西呢。第三方库呢。

我们真的需要在这里看到一些代码。识别代码中的瓶颈或阻塞调用。

node.js 不应该比 EM 快一个数量级以上。

于 2011-05-25T17:32:02.173 回答