Django中Celery任务接收后无法执行完成的问题求助
问题:Celery任务被接收后无法执行完成,无结果记录
执行环境及相关信息
本地电脑
- 操作系统:Windows 10
- Python版本:3.8
数据库服务器
- 操作系统:CentOS 7.3
- Redis版本:4.0.6
- PostgreSQL版本:10.4
相关pip包版本
Package Version celery 5.2.7 Django 3.2 django-celery-results 2.4.0 django-redis 5.2.0 redis 4.1.1
配置与代码片段
PROJECT\prj\settings.py配置
CELERY_BROKER_URL = 'redis://:' + REDIS_PASSWORD + '@' + REDIS_HOST + ':6379/1' CELERY_RESULT_BACKEND = 'django-db' CELERY_RESULT_SERIALIZER = 'json' CELERY_TASK_SERIALIZER = 'json' CELERY_ACCEPT_CONTENT = ['json'] CELERY_TIMEZONE = 'Asia/Tokyo' CELERY_TASK_TRACK_STARTED = True CELERY_TASK_TIME_LIMIT = 30 * 60
PROJECT\prj_init_.py代码
from .celery import app as celery_app __all__ = ('celery_app',)
PROJECT\prj\celery.py代码
import os from celery import Celery os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'prj.settings') app = Celery('prj') app.config_from_object('django.conf:settings', namespace="CELERY") app.autodiscover_tasks() @app.task(bind=True) def debug_task(self): print(f'Request: {self.request!r}')
PROJECT\common\task.py代码
from celery import shared_task @shared_task def load_croeds_csv(csv_file): print("start") print("end") return "ok"
PROJECT\manegements\view.py代码
class ProhibitedAreaCsvRegView(ContextRootStaff, FormView): template_name = 'manage/prohibited_area_csv.html' form_class = ProhibitedAreaCsvForm def get_context_data(self, **kwargs): context = super(ProhibitedAreaCsvRegView, self).get_context_data(**kwargs) title = "" context.update({ 'title': title, 'form': self.form_class() }) return context def form_valid(self, form): context = self.get_context_data(form=form) csv_file = form.cleaned_data["csv_file"] temp_path = save_csv_file(csv_file) result = load_croeds_csv.delay(temp_path) print(result.state) context.update({ 'result': result }) return self.render_to_response(context=context)
日志与查询结果
Worker启动日志
(venv) PROJECT>celery -A prj worker -l info -------------- celery@HP1-USER10 v5.2.7 (dawn-chorus) --- ***** ----- -- ******* ---- Windows-10-10.0.19045-SP0 2023-03-11 00:55:56 - *** --- * --- - ** ---------- [config] - ** ---------- .> app: prj:0x1aa9732be20 - ** ---------- .> transport: redis://:**@192.168.XXX.XXX:6379/1 - ** ---------- .> results: - *** --- * --- .> concurrency: 4 (prefork) -- ******* ---- .> task events: OFF (enable -E to monitor tasks in this worker) --- ***** ----- -------------- [queues] .> celery exchange=celery(direct) key=celery [tasks] . common.tasks.load_croeds_csv . configs.celery.debug_task [2023-03-11 00:55:56,890: INFO/MainProcess] Connected to redis://:**@192.168.XX.XXX:6379/1 [2023-03-11 00:55:58,306: INFO/MainProcess] celery@HP1-USER10 ready. [2023-03-11 00:56:12,928: INFO/MainProcess] Task common.tasks.load_croeds_csv[33f8c8e6-df97-4a7f-a4d5-b0286df934f3] received [2023-03-11 00:56:14,218: INFO/SpawnPoolWorker-5] child process 3020 calling self.run() [2023-03-11 00:56:14,226: INFO/SpawnPoolWorker-6] child process 15128 calling self.run() [2023-03-11 00:56:14,246: INFO/SpawnPoolWorker-7] child process 12300 calling self.run()
Redis查询结果
127.0.0.1:6379[1]> KEYS * 1) "_kombu.binding.celery.pidbox" 2) "unacked" 3) "unacked_index" 4) "_kombu.binding.celery" 5) "_kombu.binding.celeryev"
Django开发服务器日志
Watching for file changes with StatReloader System check identified no issues (0 silenced). March 11, 2023 - 00:55:48 Django version 3.2, using settings 'configs.settings' Starting development server at http://127.0.0.1:8000/ Quit the server with CTRL-BREAK. PENDING
现象
任务被Worker接收后始终无法执行完成,django-celery-results的管理后台中无任何任务记录。
可能的原因分析
- Windows系统下Celery的prefork模式兼容性问题:Celery在Windows环境下的prefork(多进程)并发模式存在已知兼容性缺陷,Worker接收任务后启动子进程时可能出现阻塞或隐性异常,导致任务无法正常推进。从Worker日志看,子进程已启动但无后续执行日志,符合该场景特征。
- 结果后端配置未生效:Worker日志中
results:字段为空,说明Worker未正确加载CELERY_RESULT_BACKEND = 'django-db'的配置,导致任务执行完成后无法将结果写入django-celery-results对应的数据库表中。需检查配置是否被正确读取,比如确认namespace="CELERY"是否与配置变量前缀匹配,或是否存在配置覆盖的情况。 - 任务参数的访问权限问题:传递给任务的
temp_path是本地文件路径,Worker子进程可能因工作目录不同、文件权限不足等原因无法访问该路径,导致任务执行卡住,无法输出"start"或"end"日志。 - Redis版本兼容性问题:你使用的Redis 4.0.6与celery 5.2.7、redis-py 4.1.1之间可能存在协议或命令兼容性差异,导致任务的ACK确认、结果传递流程出现异常,Redis中出现
unacked键也侧面说明任务状态未正常更新。 - 任务隐性异常:即使任务代码看起来简单,也可能存在隐性问题,比如Windows子进程中print输出无法正常刷新、模块导入失败等,导致任务无法正常结束,Worker无法发送结果状态。
内容的提问来源于stack exchange,提问作者AOi
相关产品推荐
相关产品推荐

