2015-04-08 3 views
2

У меня есть приложение Django 1.62, работающее на Debian 7.8 с Nginx 1.2.1 в качестве моего прокси-сервера и Gunicorn 19.1.1 в качестве моего сервера приложений. Я установил Celery 3.1.7 и RabbitMQ 2.8.4 для обработки асинхронных задач. Я пытаюсь управлять различными приложениями, в частности, Celery, используя Supervisor 3.0a8. Проблема заключается в том, что, когда я пытаюсь запустить сельдерей через супервайзер, я получаю эту ошибку: (. Я показать всю StackTrace на дне)Как избежать ошибки SECRET_KEY при запуске Celery с помощью Supervisor?

ImproperlyConfigured: The SECRET_KEY setting must not be empty. 

Все мои файлы конфигурации хранятся в " конф»каталог, который находится чуть ниже моего„MYPROJ“директории проекта, как это:

conf 
├── celeryconfig.py 
├── celeryconfig.pyc 
├── celery.py 
├── __init__.py 
├── middleware.py 
├── settings 
│   ├── base.py 
│   ├── dev.py 
│   ├── __init__.py 
│   ├── prod.py 
├── urls.py 
├── wsgi.py 

Мои производственные параметры Джанго сохраняются в файле настроек prod.py который наследуется мои base.py параметры базы. Я сохраняю секретный ключ в файле postactivate виртуальной среды, и я читаю его в своих производственных настройках, как показано ниже. Я проверил через интерпретатор Python, что секретный ключ присутствует в моих производственных настройках.

# conf/settings/prod.py 
from conf.settings.base import * 
... 
# get_env_variable is defined in base.py 
SECRET_KEY = get_env_variable("SECRET_KEY") 

Это get_env_variable функция, которая считывает секретный ключ:

# conf/settings/base.py 
def get_env_variable(var_name): 
    try: 
     return os.environ[var_name] 
    except KeyError: 
     error_msg = "Set the %s environment variable" % var_name 
     raise ImproperlyConfigured(error_msg) 

Это мой файл конфигурации супервизора. Он основан на образец файла шоу в Celery documentation:

# /etc/supervisor/conf.d/myproj.conf 
[program:myproj] 
command = /www/myproj/bin/start-gunicorn 
user = root 
stdout_logfile = /var/log/gunicorn/supervisor.log 
redirect_stderr = true 

[program:celery] 
directory=/www/myproj 
command=/home/myproj/venv/myproj/bin/celery worker --app=conf -l debug 
user=nobody 
numprocs=1 
stdout_logfile=/var/log/celery/celery.log 
stderr_logfile=/var/log/celery/celery.log 
autostart=true 
autorestart=true 
startsecs=10 
stopwaitsecs=600 
killasgroup=true 
priority=998 

Вот как я загрузил новую конфигурацию сельдерей с помощью супервизора:

sudo service supervisor stop 
sudo service supervisor start 

Это мой файл приложения сельдерея:

# conf/celery.py 
from __future__ import absolute_import 
import os 
from celery import Celery 
from django.conf import settings 
from conf import celeryconfig 

os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'conf.settings') 
app = Celery('conf') 
app.config_from_object(celeryconfig) 
app.autodiscover_tasks(lambda: settings.INSTALLED_APPS) 

Это мой файл конфигурации для сельдерея:

# conf/celeryconfig.py 
BROKER_URL = 'amqp://[email protected]:5672//' 
CELERY_RESULT_BACKEND = 'amqp' 
CELERY_ACCEPT_CONTENT = ['json', ] 
CELERY_TASK_SERIALIZER = 'json' 
CELERY_RESULT_SERIALIZER = 'json' 
CELERY_TASK_RESULT_EXPIRES = 3600 
CELERY_SEND_TASK_ERROR_EMAILS = True 

За документацию сельдерея, я модифицировал __init__.py:

# conf/__init__.py 
from __future__ import absolute_import 
from .celery import app as celery_app 

я могу начать сельдерей вручную с помощью следующей команды, и она начинает просто отлично:

workon myproj # Activate project's virtual environment 
celery worker -A conf -l info 

Однако, когда Я пытаюсь запустить его через Supervisor, я получаю описанную выше ошибку. Подумав, что, возможно, Supervisor не смог получить доступ к секретному ключу Django, потому что это переменная среды, я пробовал жестко программировать ключ в моем файле настроек prod.py (вместо того, чтобы читать его через функцию get_env_variable), но это не помогло проблема.

Я попытался объединить все мои настройки в файл настроек prod.py, содержащий фактический секретный ключ, но это не помогло.

Я также попытался добавить этот параметр среды в файле конфигурации супервизора, как показано ниже, но это не устранило проблему:

# /etc/supervisor/conf.d/myproj.conf 
... 
[program:celery] 
environment=SECRET_KEY="(my secret key)" 
directory=/www/myproj 
command=/home/myproj/venv/myproj/bin/celery worker --app=conf -l debug 
user=nobody 
... 

Я попытался установить «пользователь» к имени пользователя, который я запустите сайт, но это тоже не помогло.

# /etc/supervisor/conf.d/myproj.conf 
... 
[program:celery] 
environment=SECRET_KEY="(my secret key)" 
directory=/www/myproj 
command=/home/myproj/venv/myproj/bin/celery worker --app=conf -l debug 
user=myproj 
... 

Я прочитал о библиотеке под названием django-supervisor, которая должна облегчить интеграцию между Django и супервизора, но я получаю ту же ошибку, если я использую эту библиотеку.

Наконец, я прочитал here on SO, что если ваш секретный ключ содержит знак «%», Супервизору это не понравится. Я заметил, что мой ключ содержал один знак «%», поэтому я избежал его, как этот «%%», но это также не устранило проблему.

Может ли кто-нибудь увидеть, что я делаю неправильно? Я видел здесь другие вопросы от пользователей, которые сталкивались с этой же ошибкой при разных обстоятельствах, но я попытался реализовать различные решения, которые обсуждались, и ни одна из них не устранила проблему.

Большое спасибо за ваши идеи. И извините за длинный вопрос, но у этой проблемы много движущихся частей.

Вот вся StackTrace:

Traceback (most recent call last): 
    File "/home/myproj/venv/myproj/bin/celery", line 11, in <module> 
    sys.exit(main()) 
    File "/home/myproj/venv/myproj/local/lib/python2.7/site-packages/celery/__main__.py", line 30, in main 
    main() 
    File "/home/myproj/venv/myproj/local/lib/python2.7/site-packages/celery/bin/celery.py", line 81, in main 
    cmd.execute_from_commandline(argv) 
    File "/home/myproj/venv/myproj/local/lib/python2.7/site-packages/celery/bin/celery.py", line 769, in execute_from_commandline 
    super(CeleryCommand, self).execute_from_commandline(argv))) 
    File "/home/myproj/venv/myproj/local/lib/python2.7/site-packages/celery/bin/base.py", line 307, in execute_from_commandline 
    return self.handle_argv(self.prog_name, argv[1:]) 
    File "/home/myproj/venv/myproj/local/lib/python2.7/site-packages/celery/bin/celery.py", line 761, in handle_argv 
    return self.execute(command, argv) 
    File "/home/myproj/venv/myproj/local/lib/python2.7/site-packages/celery/bin/celery.py", line 693, in execute 
    ).run_from_argv(self.prog_name, argv[1:], command=argv[0]) 
    File "/home/myproj/venv/myproj/local/lib/python2.7/site-packages/celery/bin/worker.py", line 179, in run_from_argv 
    return self(*args, **options) 
    File "/home/myproj/venv/myproj/local/lib/python2.7/site-packages/celery/bin/base.py", line 270, in __call__ 
    ret = self.run(*args, **kwargs) 
    File "/home/myproj/venv/myproj/local/lib/python2.7/site-packages/celery/bin/worker.py", line 212, in run 
    state_db=self.node_format(state_db, hostname), **kwargs 
    File "/home/myproj/venv/myproj/local/lib/python2.7/site-packages/celery/worker/__init__.py", line 95, in __init__ 
    self.app.loader.init_worker() 
    File "/home/myproj/venv/myproj/local/lib/python2.7/site-packages/celery/loaders/base.py", line 128, in init_worker 
    self.import_default_modules() 
    File "/home/myproj/venv/myproj/local/lib/python2.7/site-packages/celery/loaders/base.py", line 116, in import_default_modules 
    signals.import_modules.send(sender=self.app) 
    File "/home/myproj/venv/myproj/local/lib/python2.7/site-packages/celery/utils/dispatch/signal.py", line 166, in send 
    response = receiver(signal=self, sender=sender, **named) 
    File "/home/myproj/venv/myproj/local/lib/python2.7/site-packages/celery/fixups/django.py", line 69, in on_import_modules 
    self.worker_fixup.validate_models() 
    File "/home/myproj/venv/myproj/local/lib/python2.7/site-packages/kombu/utils/__init__.py", line 322, in __get__ 
    value = obj.__dict__[self.__name__] = self.__get(obj) 
    File "/home/myproj/venv/myproj/local/lib/python2.7/site-packages/celery/fixups/django.py", line 64, in worker_fixup 
    self._worker_fixup = DjangoWorkerFixup(self.app) 
    File "/home/myproj/venv/myproj/local/lib/python2.7/site-packages/celery/fixups/django.py", line 99, in __init__ 
    self._cache = import_module('django.core.cache') 
    File "/usr/lib/python2.7/importlib/__init__.py", line 37, in import_module 
    __import__(name) 
    File "/home/myproj/venv/myproj/local/lib/python2.7/site-packages/django/core/cache/__init__.py", line 69, in <module> 
    if DEFAULT_CACHE_ALIAS not in settings.CACHES: 
    File "/home/myproj/venv/myproj/local/lib/python2.7/site-packages/django/conf/__init__.py", line 54, in __getattr__ 
    self._setup(name) 
    File "/home/myproj/venv/myproj/local/lib/python2.7/site-packages/django/conf/__init__.py", line 49, in _setup 
    self._wrapped = Settings(settings_module) 
    File "/home/myproj/venv/myproj/local/lib/python2.7/site-packages/django/conf/__init__.py", line 151, in __init__ 
    raise ImproperlyConfigured("The SECRET_KEY setting must not be empty.") 
django.core.exceptions.ImproperlyConfigured: The SECRET_KEY setting must not be empty. 
+0

в супервизоре config, попробуйте установить секретный ключ на 'aa'' или любую простую строку и попробуйте – ChillarAnand

+0

Спасибо за предложение, но это не решило проблему. Я изменил значение ключа, перезапустил свою виртуальную среду, сделал «env | grep SECRET», чтобы подтвердить новый секретный ключ, а затем перезапустил Celery через Supervisor, и у меня все еще есть ошибка. – William

+0

У меня были те же симптомы. Модернизация диспетчера до 3.1.3 решила проблему. Я удалил версию из APT-репозиториев и установил через pip. – abhaga

ответ

1

В вашем сельдерея конфигурации необходимо указать, какие настройки вы используете. В настоящее время у вас есть prod.py, что вы используете для вашего производства кода, чтобы ваш celery.py должен быть

# conf/celery.py 
from __future__ import absolute_import 
import os 
from celery import Celery 
from django.conf import settings 
from conf import celeryconfig 

os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'conf.settings.prod') 
app = Celery('conf') 
app.config_from_object(celeryconfig) 
app.autodiscover_tasks(lambda: settings.INSTALLED_APPS) 

Поэтому сельдерей бы знать, какие параметры файл, который вы хотите использовать (если у вас есть несколько настроек в папке настроек)