根据我奇怪的经验,Celery Beat 无法与具有 gevent 池的工作人员正常工作(计划任务被阻止并永远等待),除非您为 Beat 进程激活 gevent 猴子补丁。
但是,celery beat
不支持--pool=gevent
或-P gevent
选项。注入 gevent 猴子补丁的正确方法是使用自定义celery
二进制文件,例如:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from gevent import monkey
monkey.patch_all()
import re
import sys
from celery.__main__ import main
if __name__ == '__main__':
sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0])
sys.exit(main())
保存为celery-gevent
,运行 Beat 服务如下:
celery-gevent beat --app=proj.celery:app --loader=djcelery.loaders.DjangoLoader -f /var/log/celery/beat.log -l INFO --workdir=/my/proj --pidfile=/var/run/celery/beat.pid
在proj.celery
您还应该修补 Django 连接以避免DatabaseError
:
from __future__ import absolute_import
import os
# Set the Django settings module for the 'celery' program
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'proj.settings')
import django
# Load Django model definitions, etc
django.setup()
from django.db import connection
# Allow thread sharing to ensure that Django database connection
# works properly with gevent.
connection.allow_thread_sharing = True
from django.conf import settings
from celery import Celery
app = Celery('proj')
# Using a string here means the worker will not have to
# pickle the object when using Windows.
app.config_from_object('django.conf:settings')
app.autodiscover_tasks(lambda: settings.INSTALLED_APPS)
(上面的例子适用于 Python 2.7.10、Celery 3.1.18、Django 1.8.2 和 gevent 1.0.2)