Python分布式任务队列Celery经常卡死,如何排查和解决?
celery worker 经常卡死,例如 并发数 是 4,然后经常就有 4 个任务状态卡在 started 或者 received 不动,然后也不会抛出异常。我是设置了超时的 CELERYD_TASK_SOFT_TIME_LIMIT = 120
但是时间过了很久 也不会抛出 异常 SoftTimeLimitExceeded
我看文档是肯定会抛出的。但是这个有的时候能抛出,有的时候不会抛出,然后就卡死在那个地方! 整了一周了还是没找到问题
Python分布式任务队列Celery经常卡死,如何排查和解决?
什么版本
某些版本有这样的问题
Celery卡死通常有几个常见原因,排查时可以按这个顺序来:
-
检查Broker连接:最常见的就是RabbitMQ或Redis连接断了。用
celery -A proj inspect ping测试worker是否存活,再检查broker服务状态和网络。 -
看日志:启动worker时加
-l INFO或-l DEBUG,卡住时通常会有超时或连接错误。重点看是不是有任务hang住了。 -
任务死锁:有些任务可能卡在I/O、外部API调用或数据库长事务里。给任务设
soft_time_limit和time_limit,比如:
@app.task(soft_time_limit=60, time_limit=120)
def my_task():
# 任务逻辑
超时的任务会被中断。
-
资源泄漏:检查内存是否爆了。可以用
flower监控,或者用--maxtasksperchild参数让worker定期重启释放资源。 -
预取数太多:默认prefetch multiplier是4,如果任务长,worker可能卡在等待。启动时加
-O fair禁用预取,或者设worker_prefetch_multiplier = 1。 -
数据库连接:如果用了django-celery,数据库连接可能没关。确保每个任务结束后正确关闭db连接。
简单说就是先ping,再看日志,加超时,调参数。
用的 redis ?
celery 的确会这样,内存占用会越来越多,然后就假死,建议写个检测脚本定时重启。
或者找一个替代品例如这个: https://github.com/Bogdanp/dramatiq
rabbitmq
如果用检测脚本定时重启的话,请问怎么检测到是否假死呢?
之前做的是每隔一段时间就检测 celery 所有进程内存占用,到一定量时不管假不假死都重启。你可以根据是否有日志输出来重启。
实际我还是建议你换这个 https://github.com/Bogdanp/dramatiq,celery 我一直怀疑它内存泄漏。
感谢
用的 4.2.0
try 4.1 或者 3.1
我也是。。我头都大了。。任何异常不抛出,同时使用 beat 和 worker,会发现 beat 很好,worker 会过几天突然莫名其妙的不执行了,Received task 都没有了,但是开了 Debug 模式,没有任何异常报告。
实在不成打算用 RQ 了。不好的地方就是首先要重新学习,其次 RQ 没有原生支持类似 beat 这样的计划任务模块,但有扩展包,别人写了一个。

