调用Celery任务.delay()方法时,Gunicorn/uWSGI部署的Django出现冻结超时
问题触发原因
- celery.py文件存在重复实例化错误:你已经初始化了
app作为Celery主实例并正确加载Django配置,末尾多余的celery = Celery(__name__)和celery.config_from_object(__name__)会创建一个未加载正确Broker配置的空白Celery实例,导致运行时实例混乱,发送任务时无法正确连接Broker出现阻塞。 - 配置拼写错误:settings.py里的
CELERY_ACCEPT_CONTENt拼写错误,末尾的t应该大写为CELERY_ACCEPT_CONTENT,配置项不生效会导致任务序列化校验异常引发阻塞。 - Gunicorn/uWSGI默认prefork工作模式的fork冲突:Celery默认在进程启动时初始化连接池,prefork模式下主进程初始化Celery后fork出的子进程会复用父进程的连接池,导致连接状态异常卡住,而Django自带runserver是单进程运行,不存在fork后的连接复用问题,所以运行正常。
可行解决方案
- 修复celery.py的冗余代码,删除末尾两行多余的实例化代码,修改后完整celery.py内容如下:
import os from celery import Celery # Set the default Django settings module for the 'celery' program. os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'djangoProject.settings') app = Celery('djangoProject') # Using a string here means the worker doesn't have to serialize # the configuration object to child processes. # - namespace='CELERY' means all celery-related configuration keys # should have a `CELERY_` prefix. app.config_from_object('django.conf:settings', namespace='CELERY') # Load task modules from all registered Django apps. app.autodiscover_tasks() @app.task(bind=True) def debug_task(self): print(f'Request: {self.request!r}')
- 修正settings.py中的配置拼写错误,将
CELERY_ACCEPT_CONTENt改为CELERY_ACCEPT_CONTENT。 - 修复prefork模式的连接池冲突,任选以下一种方案即可:
- 方案一:在settings.py中添加配置禁用父进程预创建连接,同时调整Gunicorn启动参数:
启动Gunicorn时添加CELERY_BROKER_TRANSPORT_OPTIONS = {'max_retries': 3}--preload参数,让应用代码在fork子进程前完全加载,也可直接切换Gunicorn/uWSGI的工作模式为gevent/eventlet异步模式。 - 方案二:添加进程fork后重置Celery连接的钩子,在项目的wsgi.py文件末尾添加以下代码:
from djangoProject.celery import app as celery_app import celery.signals @celery.signals.worker_process_init.connect def fix_celery_connection(**kwargs): celery_app.close() celery_app.broker_connection().connection.connect()
- 方案一:在settings.py中添加配置禁用父进程预创建连接,同时调整Gunicorn启动参数:
内容的提问来源于stack exchange,提问作者Ashutosh Singh
相关产品推荐
相关产品推荐

