Django进程直接执行异步任务而非Celery worker的问题求助
问题排查与解决步骤
1. 先修正异步任务调用方式
你当前 views.py 中的任务是同步调用写法,本身就会直接在Django进程中执行,不会提交到Celery worker。如果要异步执行,必须加.delay()后缀:
# 修正后的调用写法 tasks.remove_task.delay(environment=environment, payload=request.data)
你提到加了.delay()后出现阻塞、无日志,属于配置错误导致,按以下顺序排查:
2. 修正Celery Broker配置命名
这是你当前最核心的配置错误:
你在 celery.py 中指定了 namespace='CELERY',意味着Celery只会读取settings.py中前缀为CELERY_的配置项。但你当前把Broker地址赋值给了没有前缀的BROKER_URL变量,Celery读取不到正确的Broker地址,默认会尝试连接本机RabbitMQ,连不上就会出现无限阻塞的情况。
修改settings.py中的配置即可:
# 把BROKER_URL改为带CELERY_前缀的CELERY_BROKER_URL CELERY_BROKER_URL = CELERY_RESULT_BACKEND = ( f'redis://{CELERY_REDIS_HOST}:{CELERY_REDIS_PORT}/{CELERY_REDIS_DB}' )
3. 检查项目根目录__init__.py配置
确保你的Django项目根目录(和settings.py、celery.py同目录)的__init__.py中加入了以下内容,保证Django启动时能加载Celery实例:
from .celery import app as celery_app __all__ = ('celery_app',)
4. 排查Redis连通性
在Django运行的环境中执行redis-cli -h [你的Redis主机地址] -p 6379 -n [你配置的CELERY_REDIS_DB],确认可以正常连接Redis,如果Redis设置了密码,需要在连接串中补充密码:
CELERY_BROKER_URL = CELERY_RESULT_BACKEND = ( f'redis://:{你的Redis密码}@{CELERY_REDIS_HOST}:{CELERY_REDIS_PORT}/{CELERY_REDIS_DB}' )
5. 检查Celery相关特殊配置
确认settings.py中没有设置CELERY_TASK_ALWAYS_EAGER = True,这个参数会强制所有异步任务同步在调用进程执行,不会提交给worker。如果有该配置,删除或者设置为False即可。
6. 验证Worker启动参数
启动Celery worker时要指定正确的App路径,你的项目名为maat,启动命令应为:
celery -A maat worker -l info
启动后观察控制台输出的Broker地址,如果显示为redis://xxx说明配置生效,如果显示为amqp://guest@localhost:5672//则说明Broker配置仍未正确读取。
内容的提问来源于stack exchange,提问作者fernandezcuesta

