Delayed Job ActiveRecord::Job Load - 每5秒运行一次?

5

我有一种感觉,这就是Rails版的疑病症...但我看了一眼 tail -f logs/development.log,然后被输出所迷住:

  Delayed::Backend::ActiveRecord::Job Load (0.8ms)  UPDATE "delayed_jobs" SET locked_at = '2016-08-26 12:49:09.594888', locked_by = 'host:ghost pid:4564' WHERE id IN (SELECT  "delayed_jobs"."id" FROM "delayed_jobs" WHERE ((run_at <= '2016-08-26 12:49:09.594275' AND (locked_at IS NULL OR locked_at < '2016-08-26 08:49:09.594332') OR locked_by = 'host:ghost pid:4564') AND failed_at IS NULL) ORDER BY priority ASC, run_at ASC LIMIT 1 FOR UPDATE) RETURNING *
  Delayed::Backend::ActiveRecord::Job Load (0.5ms)  UPDATE "delayed_jobs" SET locked_at = '2016-08-26 12:49:14.651262', locked_by = 'host:ghost pid:4564' WHERE id IN (SELECT  "delayed_jobs"."id" FROM "delayed_jobs" WHERE ((run_at <= '2016-08-26 12:49:14.650707' AND (locked_at IS NULL OR locked_at < '2016-08-26 08:49:14.650765') OR locked_by = 'host:ghost pid:4564') AND failed_at IS NULL) ORDER BY priority ASC, run_at ASC LIMIT 1 FOR UPDATE) RETURNING *
  Delayed::Backend::ActiveRecord::Job Load (0.5ms)  UPDATE "delayed_jobs" SET locked_at = '2016-08-26 12:49:19.716179', locked_by = 'host:ghost pid:4564' WHERE id IN (SELECT  "delayed_jobs"."id" FROM "delayed_jobs" WHERE ((run_at <= '2016-08-26 12:49:19.715433' AND (locked_at IS NULL OR locked_at < '2016-08-26 08:49:19.715494') OR locked_by = 'host:ghost pid:4564') AND failed_at IS NULL) ORDER BY priority ASC, run_at ASC LIMIT 1 FOR UPDATE) RETURNING *

这个程序每五秒运行一次。所以,这正常吗?

我想到了Delayed Job必须要通过检查作业时间戳来工作,这就是它在执行的事情,但我没有找到任何有力的书面证据。

如果是这样的话,我的第二个担忧是这样做会不会在我的Heroku实例上浪费很多钱?我已经安装了workless gem来尝试减轻成本,但我没有看到任何代码来关闭它...

是个小错误还是一个功能,如何才能避免破产?

3个回答

4
这确实是延迟作业的工作方式。默认的sleep_delay为5秒钟(源代码)。
您可以在初始化器中配置自定义延迟,如这里所述。查找sleep_delay即可。

4

我会尽力回答您的问题,比其他人更全面。

是的,这是正常行为。当您启动Delayed Job进程时,它会以可配置的时间间隔检查未处理的作业是否存在于数据库中。(默认间隔为5秒,并且您可以使用Delayed::Worker.sleep_delay设置将其配置为不同的间隔)

您说的没错,Delayed Job在其周期性检查之一期间,会检查需要完成的下一个可用作业,然后运行它。

为了高效运行Delayed Job,通常需要保持一个工作dyno处于打开状态,以不断地检查新的作业是否需要运行。

但是,在您提问中链接的workless gem可以帮助您解决这个问题。与其需要工作dyno 24/7来检查新作业,workless仅在队列中有作业需要运行时才启动工作dyno。当作业完成后,workless关闭工作dyno。

您可以在workless的README中阅读有关此行为的描述

Workless的工作原理?

  • Delayed::Workless::Scaler被混合到Delayed::Job类中,从而添加了一些回调。
  • 当在数据库上创建作业时,创建回调会启动一个工作程序。
  • 该工作程序运行作业并将其从数据库中删除。
  • 销毁回调停止工人。

但是总会有权衡的。启动工作dyno需要时间,因此处理新作业不会那么即时。例如,使用持续运行的工作dyno,您的作业通常会在5秒内运行。如果改用workless,则需要大约30秒才能启动dyno并让Delayed Job获得作业。显然,可接受性取决于您的应用程序,因此完全由您决定。


1
非常感谢Chris - 你的回答很棒,特别是列出了权衡利弊。 - Huw

1

添加以下行并根据需要更改频率值。

#initializers/delayed_job_config.rb
Delayed::Worker.sleep_delay = 60 #for a 60 second sleep time.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接