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

跨服务器调用Celery任务报错:未注册任务'tasks.test'如何解决?

跨服务器调用Celery任务时未注册任务错误的解决办法

问题背景

两台服务器部署架构:

  • 服务器1:Django应用 + Redis(作为Celery Broker)
  • 服务器2:Celery Worker

Celery服务器(服务器2)的task.py代码:

from celery import Celery

app = Celery('tasks')
app.conf.broker_url = 'redis://localhost:6379/0'

@app.task(bind=True)
def test():
    print('Testing')

Django服务器(服务器1)调用任务的代码:

from celery import Celery
celery = Celery()
celery.conf.broker_url = 'redis://localhost:6379/0'
celery.send_task('tasks.test')

启动Celery Worker的命令:

celery -A tasks worker --loglevel=INFO

调用时触发错误:

收到类型为'tasks.test'的未注册任务。消息已被忽略并丢弃。
您是否记得导入包含该任务的模块?或者您是否使用了相对导入?

解决方法

1. 修正Redis连接地址

如果Redis部署在Django服务器(服务器1),Celery服务器(服务器2)的broker_url不能写localhost,必须替换为Django服务器的公网IP或内网地址,否则Worker无法连接到正确的Broker,导致任务无法被正确注册和接收。

修改服务器2的task.py:

from celery import Celery

# 替换为Django服务器的实际IP/域名
app = Celery('tasks', broker='redis://<Django服务器IP>:6379/0')

@app.task(bind=True)
def test():
    print('Testing')

2. 确保Worker正确加载任务模块

启动Worker时,确认task.py在当前工作目录,或者通过绝对路径指定模块:

# 替换为task.py所在的绝对路径
celery -A /full/path/to/tasks worker --loglevel=INFO

启动后查看Worker日志,确认是否有tasks.test任务被注册的日志信息,若没有则说明Worker未找到任务模块,需调整路径。

3. 统一任务命名与显式注册

给任务指定明确的名称,避免命名匹配问题:

from celery import Celery

app = Celery('tasks', broker='redis://<Django服务器IP>:6379/0')

# 显式指定任务名称,确保和调用端一致
@app.task(bind=True, name='tasks.test')
def test():
    print('Testing')

# 或者让Celery自动发现任务模块
app.autodiscover_tasks(['tasks'])

4. 更可靠的调用方式:共享任务模块

将task.py作为公共代码同步到Django服务器和Celery服务器,Django端直接导入任务调用,无需使用send_task:

在Django项目中添加task.py(和服务器2的代码一致),然后调用:

from tasks import test
# 使用delay()或apply_async()触发任务
test.delay()

这种方式依赖Celery自动管理任务名称,能有效避免名称匹配错误。

内容的提问来源于stack exchange,提问作者Arsh Doda

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 09:42:05