Celery AsyncResult.state 始终处于PENDING状态排查求助(Ubuntu)
Celery任务始终处于
PENDING状态无报错的排查方案 问题描述
在Ubuntu环境下提交Celery任务后,任务状态始终停留在PENDING,无任何报错日志输出。
任务代码
from celery import Celery from django.conf import settings app = Celery( 'api', broker=settings.CELERY_BROKER_URL, backend=settings.CELERY_BROKER_URL, timezone=settings.CELERY_TIMEZONE, task_track_started=settings.CELERY_TASK_TRACK_STARTED, task_time_limit=settings.CELERY_TASK_TIME_LIMIT, broker_connection_retry_on_startup=settings.CELERY_BROKER_CONNECTION_RETRY_ON_STARTUP, ) # This would fail to connect because I couldn't get TLS to work this way # app.config_from_object('django.conf:settings', namespace='CELERY') app.autodiscover_tasks() @app.task(queue='periodic') def some_task(corpus_id): return 123
任务提交代码
r = some_task.apply_async([4], queue='gpu') r.state == 'PENDING'
Worker日志
-------------- celery@gpuworker v5.4.0 (opalescent) --- ***** ----- -- ******* ---- Linux-5.15.0-118-generic-x86_64-with-glibc2.39 2024-09-10 21:55:59 - *** --- * --- - ** ---------- [config] - ** ---------- .> app: api:0x7ff754494700 - ** ---------- .> transport: rediss://redis:6379/1 - ** ---------- .> results: rediss://redis:6379/1 - *** --- * --- .> concurrency: 1 (prefork) -- ******* ---- .> task events: OFF (enable -E to monitor tasks in this worker) --- ***** ----- -------------- [queues] .> gpu exchange=gpu(direct) key=gpu [tasks] . api.celery.some_task [2024-09-10 21:55:59,900: INFO/MainProcess] Connected to rediss://redis:6379/1 [2024-09-10 21:55:59,974: INFO/MainProcess] mingle: searching for neighbors [2024-09-10 21:56:01,098: INFO/MainProcess] mingle: all alone [2024-09-10 21:56:01,406: INFO/MainProcess] celery@gpuworker ready.
已完成的排查
- 通过
app.control.inspect()检查任务状态,所有结果均返回None:i = app.control.inspect() i.reserved(), i.active(), i.registered(), i.scheduled() # (None, None, None, None) - 确认
app与some_task.app为同一实例:<Celery api at 0x7f26e52b71c0> <Celery api at 0x7f26e52b71c0>
排查建议与解决方案
1. 修正队列不匹配问题
任务定义时指定的队列是periodic,但提交任务时指定了gpu队列。虽然Worker监听gpu队列,但任务路由规则存在冲突:
- 要么修改任务定义的队列:
@app.task(queue='gpu') - 要么提交任务时使用默认的
periodic队列,同时启动监听该队列的Worker
2. 排查Redis TLS连接问题
代码中注释了app.config_from_object并说明TLS连接失败,当前将CELERY_BROKER_URL同时作为结果后端,需确认Redis TLS配置:
- 检查
settings.CELERY_BROKER_URL格式是否正确,是否包含ssl_ca_certs等必要参数 - 用Redis客户端直接连接
rediss://redis:6379/1,验证连接是否正常 - 可临时禁用TLS(改用
redis://)测试任务是否正常执行,排除TLS因素
3. 解决app.control.inspect()返回None的问题
inspect返回None意味着Worker与提交端的Celery实例无法通信:
- 确认Worker和提交任务的应用使用完全相同的Celery配置(broker URL、app名称等)
- 检查Redis中是否存在Celery控制通道键(如
celery@gpuworker.control),确保Worker已正确注册到broker
4. 验证结果后端配置
当前将broker URL同时作为结果后端,需确认Redis作为结果后端的配置是否生效:
- 手动在Redis数据库1中写入测试键值对,验证应用能否正常读写
- 检查Celery是否有权限访问Redis数据库1(URL中的
/1指定的库)
5. 开启任务事件监控
启动Worker时添加-E参数开启事件监控,再用celery events查看任务流:
celery -A api worker -l info -Q gpu -E celery -A api events
通过事件监控可直观查看任务是否被Worker接收、处理。
6. 确认任务注册正确性
检查Worker日志的[tasks]部分,确认api.celery.some_task是否正确注册。若未发现任务:
- 确保
autodiscover_tasks()能扫描到任务所在模块 - 手动指定任务模块:
app.autodiscover_tasks(['your_app.tasks'])
内容的提问来源于stack exchange,提问作者Herbert
相关产品推荐
相关产品推荐

