Celery 工作线程挂起,没有任何错误

问题描述 投票:0回答:4

我有一个用于运行 celery 工作人员的生产设置,用于向远程服务发出 POST / GET 请求并存储结果,它每 15 分钟处理大约 20k 任务的负载。

问题是工作人员无缘无故地变得麻木,没有错误,没有警告。

我也尝试过添加多处理,结果相同。

在日志中我看到执行任务的时间增加了,就像在 s 中成功了

有关更多详细信息,请参阅https://github.com/celery/celery/issues/2621

python celery blocking gevent
4个回答
41
投票

如果你的 celery Worker 有时会卡住,你可以使用

strace & lsof
来找出卡在哪个系统调用处。

例如:

$ strace -p 10268 -s 10000
Process 10268 attached - interrupt to quit
recvfrom(5,

10268是celeryworker的pid,

recvfrom(5
表示worker停止从文件描述符接收数据。

然后你可以使用

lsof
来查看这个工作进程中的
5
是什么。

lsof -p 10268
COMMAND   PID USER   FD   TYPE    DEVICE SIZE/OFF      NODE NAME
......
celery  10268 root    5u  IPv4 828871825      0t0       TCP 172.16.201.40:36162->10.13.244.205:wap-wsp (ESTABLISHED)
......

这表明工作线程卡在 TCP 连接上(您可以在

5u
列中看到
FD
)。

一些Python包如

requests
会阻塞等待来自peer的数据,这可能会导致celery工作挂起,如果您使用
requests
,请确保设置
timeout
参数。


您看过此页面吗:

https://www.caktusgroup.com/blog/2013/10/30/using-strace-debug-stuck-celery-tasks/


5
投票

当我使用延迟共享任务时,我也遇到了这个问题 芹菜、昆布、amqp、台球。我使用时调用API后 @shared_task 的延迟(),所有功能都很好,但是当它延迟时 它挂了。

所以,问题是在主应用程序init.py中,以下设置 失踪了

这将确保在 Django 启动时始终导入该应用程序,以便共享任务将使用该应用程序。

init.py

from __future__ import absolute_import, unicode_literals

# This will make sure the app is always imported when
# Django starts so that shared_task will use this app.
from .celery import app as celeryApp

#__all__ = ('celeryApp',)
__all__ = ['celeryApp']
    

注意1:代替celery_app放置应用程序名称,表示celery.py中提到的应用程序导入应用程序并放在这里

注2:**如果仅在共享任务中遇到挂起问题,上述解决方案可能会解决您的问题并忽略以下问题。

还想提一下 A=另一个问题,如果有人遇到错误 111 连接问题请检查 amqp==2.2.2 的版本, 台球==3.5.0.3,芹菜==4.1.0,昆布==4.1.0 是否 支持与否。提到的版本只是一个例子。并且 检查你的系统中是否安装了redis(如果有使用redis)。

还要确保您使用的是 Kombu 4.1.0。在最新版本中 Kombu 将异步重命名为异步。


0
投票

另一种情况:RabbitMq 磁盘可用空间不足:

来自 RabbitMq 文档

当可用磁盘空间低于配置的限制(默认为 50 MB)时,将触发警报并阻止所有生产者。

您应该将rabbitmq可用磁盘空间增加到配置限制以上。

相关芹菜主题了解更多信息。


-6
投票

按照本教程操作

芹菜 Django 链接

将以下内容添加到设置中

注意安装 redis 用于传输和结果

   # TRANSPORT
   CELERY_BROKER_TRANSPORT = 'redis'
   CELERY_BROKER_HOST = 'localhost'
   CELERY_BROKER_PORT = '6379'
   CELERY_BROKER_VHOST = '0'

   # RESULT
   CELERY_RESULT_BACKEND = 'redis'
   CELERY_REDIS_HOST = 'localhost'
   CELERY_REDIS_PORT = '6379'
   CELERY_REDIS_DB = '1'
© www.soinside.com 2019 - 2024. All rights reserved.