每当我使用capistrano部署或运行cap production delayed_job:restart
时,我最终都会锁定当前运行的delayed_job行。
delayed_job进程成功停止,新的delayed_job进程启动,新进程锁定了新的行。问题是最后一个进程的行仍然在那里,标记为锁定。所以我必须手动进入数据库,删除该行,然后手动将该作业添加回队列,以便新的delayed_job进程访问。
是否有一种方法可以自动进行数据库清理和重新排队?
每当我使用capistrano部署或运行cap production delayed_job:restart
时,我最终都会锁定当前运行的delayed_job行。
delayed_job进程成功停止,新的delayed_job进程启动,新进程锁定了新的行。问题是最后一个进程的行仍然在那里,标记为锁定。所以我必须手动进入数据库,删除该行,然后手动将该作业添加回队列,以便新的delayed_job进程访问。
是否有一种方法可以自动进行数据库清理和重新排队?
2条答案
按热度按时间rta7y2nd1#
我也有同样的问题。每当一个作业被强制杀死时,就会发生这种情况。部分问题是工人进程由守护进程gem管理,而不是delayed_job本身。我目前正在研究解决这个问题的方法,例如:
我会回到这里,如果我想出一个解决方案。
h79rfbju2#
调整守护程序等待时间或在
SIGINT
上引发异常。@John Carney是正确的。简而言之,所有的
delayed_job
worker在重新部署时都会收到类似SIGINT
(漂亮的中断)的消息。默认情况下,delayed_job
worker会完成当前的作业(如果他们正在处理一个作业),然后优雅地终止。但是,如果他们正在处理的作业是一个运行时间较长的作业,则Daemon管理器在生气并发送更严重的中断信号(如
SIGTERM
或SIGKILL
)之前会等待一段时间。此等待时间以及发送的内容实际上取决于您的设置和配置。当这种情况发生时,
delayed_job
工作线程会立即被杀死,而无法完成它正在处理的作业,甚至无法在自己完成后进行清理,并将作业标记为不再锁定。这最终导致一个“搁浅”的作业,它被标记为“锁定”,但被锁定到一个不再存在的进程/worker。
这就是问题的症结所在。要解决这个问题,你有两个主要的选择,这取决于你的工作是什么样子的(我们两个都用):
1.收到中断时引发异常。
您可以通过将
raise_signal_exceptions
配置设置为:term
或true
来完成此操作:字符串
此配置选项接受
:term
、true
或false
(默认)。您可以阅读有关原始提交here的更多信息。我会先尝试使用
:term
,看看这是否解决了你的问题。如果没有,你可能需要将它设置为true
。设置为
:term
或true
将正常引发异常并解锁作业,以便另一个delayed_job
工作进程拾取作业并开始处理它。将其设置为
true
意味着您的delayed_job
工作线程甚至不会尝试完成他们正在处理的当前作业。他们将立即引发异常,解锁作业并终止自己。2.调整您的工作线程在重新部署时的中断/终止/终止方式。
这真的取决于你的重新部署,等等。在我们的例子中,我们使用Cloud 66来处理部署,所以我们只需要用它们来配置它。但这是我们的样子:
型
在重新部署时,这会告诉守护程序管理器对每个
delayed_job
工作进程执行以下步骤:1.发送
SIGINT
。1.等待172800秒(2天)-我们有 * 非常 * 长时间运行的作业。
1.如果worker还活着,发送
SIGTERM
。1.等待90秒。
1.如果worker还活着,发送
SIGKILL
。无论如何,这应该有助于让你走上正确的轨道,为自己正确地配置它。
我们使用这两种方法,设置一个较长的超时时间,并在收到
SIGTERM
时引发异常。这确保了如果有一个作业运行超过2天的限制,它至少会引发一个异常并解锁作业,从而允许我们进行调查,而不仅仅是留下一个被锁定到不再存在的进程的搁浅作业。