rq (redis queue) work-horse 意外终止,关于如何调试的建议?
rq (redis queue) work-horse terminated unexpectedly, suggestions on how to debug?
我正在使用 RQ worker 处理大量作业,但我遇到了问题。
观察
- 工作returns
work-horse terminated unexpectedly; waitpid returned None
- 该作业连接到数据库并简单地 运行 几个 SQL 语句,如简单的插入或删除语句。
- 错误消息几乎立即出现:在启动后的几秒钟内。
- 有时工作 运行 很好,没有问题。
- 在其中一项作业中,我可以看到它进行了插入,但随后 returns 出现了错误。
- 在 rq worker 上,我看到以下日志条目。
{"message": "my_queue: my_job() (dcf797c4-1434-4b77-a344-5bbb1f775113)"}
{"message": "Killed horse pid 8451"}
{"message": "Moving job to FailedJobRegistry (work-horse terminated unexpectedly; waitpid returned None)"}
- 深入研究 rq 代码 (https://github.com/rq/rq),"Killed horse pid..." 行提示 RQ 故意终止作业本身。作业终止代码发生的唯一地方是在以下代码段中。要到达
self.kill_horse()
行,必须发生 HorseMonitorTimeoutException
并且 utcnow - job.started_at
差异必须 > job.timeout(顺便说一句,超时时间很长)。
while True:
try:
with UnixSignalDeathPenalty(self.job_monitoring_interval, HorseMonitorTimeoutException):
retpid, ret_val = os.waitpid(self._horse_pid, 0)
break
except HorseMonitorTimeoutException:
# Horse has not exited yet and is still running.
# Send a heartbeat to keep the worker alive.
self.heartbeat(self.job_monitoring_interval + 5)
# Kill the job from this side if something is really wrong (interpreter lock/etc).
if job.timeout != -1 and (utcnow() - job.started_at).total_seconds() > (job.timeout + 1):
self.kill_horse()
break
- 有时,在工作人员真正到达它们之前,作业会在队列中停留很长时间。不过,我本来希望 started_at 会被重置。这个假设可能是错误的。
- 作业是使用 rq_scheduler 创建的,它们使用 cron 字符串定期触发(每天晚上 11 点,等等)
我接下来应该怎么做?
我认为最新版本的 RQ (https://github.com/rq/rq/releases/tag/v1.4.0) 有解决方案。
Fixed a bug that may cause early termination of scheduled or requeued jobs. Thanks @rmartin48!
我正在使用 RQ worker 处理大量作业,但我遇到了问题。
观察
- 工作returns
work-horse terminated unexpectedly; waitpid returned None
- 该作业连接到数据库并简单地 运行 几个 SQL 语句,如简单的插入或删除语句。
- 错误消息几乎立即出现:在启动后的几秒钟内。
- 有时工作 运行 很好,没有问题。
- 在其中一项作业中,我可以看到它进行了插入,但随后 returns 出现了错误。
- 在 rq worker 上,我看到以下日志条目。
{"message": "my_queue: my_job() (dcf797c4-1434-4b77-a344-5bbb1f775113)"}
{"message": "Killed horse pid 8451"}
{"message": "Moving job to FailedJobRegistry (work-horse terminated unexpectedly; waitpid returned None)"}
- 深入研究 rq 代码 (https://github.com/rq/rq),"Killed horse pid..." 行提示 RQ 故意终止作业本身。作业终止代码发生的唯一地方是在以下代码段中。要到达
self.kill_horse()
行,必须发生HorseMonitorTimeoutException
并且utcnow - job.started_at
差异必须 > job.timeout(顺便说一句,超时时间很长)。
while True:
try:
with UnixSignalDeathPenalty(self.job_monitoring_interval, HorseMonitorTimeoutException):
retpid, ret_val = os.waitpid(self._horse_pid, 0)
break
except HorseMonitorTimeoutException:
# Horse has not exited yet and is still running.
# Send a heartbeat to keep the worker alive.
self.heartbeat(self.job_monitoring_interval + 5)
# Kill the job from this side if something is really wrong (interpreter lock/etc).
if job.timeout != -1 and (utcnow() - job.started_at).total_seconds() > (job.timeout + 1):
self.kill_horse()
break
- 有时,在工作人员真正到达它们之前,作业会在队列中停留很长时间。不过,我本来希望 started_at 会被重置。这个假设可能是错误的。
- 作业是使用 rq_scheduler 创建的,它们使用 cron 字符串定期触发(每天晚上 11 点,等等)
我接下来应该怎么做?
我认为最新版本的 RQ (https://github.com/rq/rq/releases/tag/v1.4.0) 有解决方案。
Fixed a bug that may cause early termination of scheduled or requeued jobs. Thanks @rmartin48!