我们在大部分项目中都使用了Resque,并且对其感到满意。
在最近的一个项目中,我们遇到了这样一种情况:我们需要从Twitter的实时流API建立连接。由于我们需要保持连接,我们将每个来自流API的行都存入到一个Resque队列中,以防止连接丢失。然后我们会在之后处理这个队列。
我们发现插入速率大约是每秒30-40个,而弹出速率仅有每秒3-5个。因此,队列总是在增加。当我们查找原因时,发现Resque有一个父进程,对于队列中的每个作业,它都会派生一个子进程来处理该作业。由于我们的rails环境相当繁重,子进程派生需要花费时间。
因此,我们目前实现了另一个类似的rake任务:
rake :process_queue => :environment do
while true
begin
interaction = Resque.pop("process_twitter_resque")
if interaction
ProcessTwitterResque.perform(interaction)
end
rescue => e
puts e.message
puts e.backtrace.join("\n")
end
end
end
并且像这样开始任务:
nohup bundle exec rake process_queue --trace >> log/workers/process_queue/worker.log 2>&1 &
这并没有处理失败的作业等情况。
但是,我的问题是为什么Resque要实现一个子进程来处理队列中的作业。这些作业明确不需要并行处理(因为它是一个队列,我们期望它按顺序一个接一个地处理,我相信Resque也一次只fork一个子进程)。
我相信Resque肯定有某个目的。这种父/子进程架构背后的确切目的是什么?