Heroku环境下Celery delay()调用无响应问题排查请求
我来帮你梳理下当前配置里的几个关键问题,这些应该就是导致add.delay(2,3)卡住的核心原因:
1. Procfile中的Worker启动命令错误
你当前的Procfile里worker的启动命令是:
worker: celery worker --app=tasks.app
但你的Celery应用实例是定义在project/celery.py里的app,正确的启动命令应该指向这个路径,改成:
worker: celery worker --app=project.celery:app --loglevel=info
之前的命令找不到正确的Celery实例,导致worker没真正接入你的任务队列,任务发出去后没人处理,自然就会卡住。
2. Celery配置冲突
你在project/celery.py里手动设置了BROKER_URL和CELERY_RESULT_BACKEND,但同时又用了app.config_from_object('django.conf:settings', namespace='CELERY'),而且settings里还注释了CELERY_RESULT_BACKEND,这会导致配置逻辑混乱。
建议把所有Celery配置统一放到project/settings.py里:
# settings.py 关键配置片段 INSTALLED_APPS = [ ... 'django_celery_results', 'Buylist', ] # Celery核心配置 CELERY_BROKER_URL = os.environ.get('REDIS_URL') # 若想用django_celery_results将结果存在数据库,用下面这行 CELERY_RESULT_BACKEND = 'django-db' # 若仍想用Redis存储结果,就用这行 # CELERY_RESULT_BACKEND = os.environ.get('REDIS_URL')
然后删掉project/celery.py里的这行手动配置:
app.conf.update(BROKER_URL=os.environ['REDIS_URL'], CELERY_RESULT_BACKEND=os.environ['REDIS_URL'])
因为namespace='CELERY'会自动读取settings里带CELERY_前缀的配置,这样配置更统一,不会出现冲突。
3. 确认Redis连接正常
先验证你的Heroku Redis实例能不能正常连接,在终端运行:
heroku run python
然后在Python交互环境里测试:
import os import redis r = redis.from_url(os.environ['REDIS_URL']) r.set('test_key', 'hello_celery') print(r.get('test_key'))
如果能输出b'hello_celery',说明Redis连接没问题;如果报错,可能是Redis实例没正确绑定,或者环境变量REDIS_URL未配置到位。
4. 检查Worker的运行状态
修改Procfile后,重新部署并启动worker:
git add . git commit -m "fix celery worker config" git push heroku main heroku ps:scale worker=1
然后运行heroku ps查看worker状态,如果显示up,说明启动成功;如果是crash或者starting,就查看worker日志排查错误:
heroku logs --ps worker
日志里会明确告诉你启动失败的原因,比如依赖缺失、路径错误等。
5. 清理tasks.py的冗余代码
你的Buylist/tasks.py里有一些多余的导入:
from celery import Celery from celery.schedules import crontab
这些完全不需要,因为你用的是shared_task,只需要保留from celery import shared_task即可,冗余导入可能会导致潜在的配置冲突,删掉它们即可。
做完这些修改后,重新部署,再测试add.delay(2,3),应该就能正常执行了。后续配置Celery Beat的时候,记得在Procfile里添加beat的启动命令,比如:
beat: celery beat --app=project.celery:app --loglevel=info
然后运行heroku ps:scale beat=1启动beat服务即可。
内容的提问来源于stack exchange,提问作者juju

