You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 11:17:08