WorkerLostError('工作进程过早退出:信号15(SIGTERM)。',)

2024-06-25 23:12:03 发布

您现在位置:Python中文网/ 问答频道 /正文

我最近开始在一个新的Django项目中使用芹菜。设置:

 -------------- celery@123 v3.1.7 (Cipater) 
---- **** -----  
--- * ***  * -- Linux-3.8.11-ec2-x86_64-with-debian-squeeze-sid 
-- * - **** ---  
- ** ---------- [config] 
- ** ---------- .> app:         nextlanding_api:0x1c23250 
- ** ---------- .> transport:   redis://rediscloud@123123 
- ** ---------- .> results:     djcelery.backends.database:DatabaseBackend 
- *** --- * --- .> concurrency: 4 (prefork) 
-- ******* ----  
--- ***** ----- [queues] 
 -------------- .> celery           exchange=celery(direct) key=celery 

software -> celery:3.1.7 (Cipater) kombu:3.0.8 py:2.7.4
            billiard:3.3.0.13 redis:2.9.0
platform -> system:Linux arch:64bit, ELF imp:CPython
loader   -> celery.loaders.app.AppLoader
settings -> transport:redis results:djcelery.backends.database:DatabaseBackend 

我正在调查一个问题,即eta为24小时以上的任务正在消失(我已经确保了visibility_timeoutis>;24小时)。当我热情地关闭这个工人时,日志语句显示了几个被确认的消息。例子: Restoring 26 unacknowledged message(s).

但是,我希望恢复大约50条未确认的消息。仔细观察我的日志,我发现:

[ERROR] celery.worker.job: Task myproj_task[xxx] raised unexpected: WorkerLostError('Worker exited prematurely: signal 15 (SIGTERM).',)
...
WorkerLostError: Worker exited prematurely: signal 15 (SIGTERM). 
Restoring 26 unacknowledged message(s). 
Process exited with status 0 

我见过其他人报告OOM杀死了他们的进程。我在Heroku上,没有看到R14代码。

最后一点,我正在从我的任务中产生新的进程。

我的问题是:工作失误是我应该担心的吗?状态代码是15(SIGTERM),看起来正常。如果此错误不正常,是否可能导致ETA任务丢失?

编辑

起初我以为项目会消失,但在放入一些详细的日志后,我可以看到任务已经发出,但从未在redis中持久化:

myproj_email_task was sent. task_id: b6ce2b97-d5b8-4850-9e43-9185426cd9f6

但是,查看redis中的任务时,任务b6ce2b97-d5b8-4850-9e43-9185426cd9f6不存在。

因此,任务似乎没有消失,但要么根本没有发送,要么没有放入unackedredis密钥。


Tags: 项目redisapptasklinuxwithresultsbackends
3条回答

工作失误是不正常的,你一定要担心。

至于长时间运行的作业上的ack/restarts:芹菜做得最好,但是如果您偏执,并且您期望有一个保证的交付/执行/ack模型,即使父/工作进程在异常情况下死亡,您也可以考虑使用辅助数据存储来跟踪进度和元数据,以便进行精细的控制:

Client->TransactionalDB: insert JOB
Client->Celery: send_async(job_id)
Celery->Worker: do(job_id)
Worker->TransactionalDB: update started job + meta
...
Worker->TransactionalDB: update progress + meta
...
?->Worker: die!
...
Celerybeat->Worker: checkForOrphans()
Worker->TransactionalDB: select where ... 

这些工作失误的原因很可能是芹菜和Heroku的行为不协调:

  • 芹菜工人希望在父工作进程上有一个SIGTERM,在这种情况下,它允许其子进程完成其当前任务。
  • 当对dyno进行“热关机”时,Heroku会向dyno中的所有进程发送一个SIGTERM。

因此,所有的worker子进程也会得到SIGTERM并立即开始终止,从而导致WorkerLostErrors。

为未发行的芹菜4.0准备了一个解决方案:https://github.com/celery/celery/issues/2839

我还没有找到3.1.19的解决方案。

SIGTERM上的WorkerLost绝对不正常。在这种情况下,如何能够在不丢失任务的情况下重新启动进程?即使是ack_late选项也没有帮助。

我认为不要在SIGTERM上丢失任务的愿望远非妄想。

相关问题 更多 >