Celery RuntimeError: populate () не реентерабелен - PullRequest
0 голосов
/ 13 марта 2019

Я могу запустить рабочий из CLI, но не из супервизора.Я пытался запустить его под разными пользователями, и он работал на некоторых, а не на других.Он всегда работал как root.Поэтому я подумал, что это может быть связано с некоторыми переменными или разрешениями среды.

Но lol

Местоположение проекта находится в / opt / data / project и установлено как chown apache: apache -R / opt / data / project

supervisor 3.4.4 django 1.11.3 сельдерей 4.2.1

Я сделал в значительной степени стандартную конфигурацию

cat /opt/project/CORE/CORE/celery.py

from __future__ import absolute_import, unicode_literals
import os
from celery import Celery
# from django.conf import settings

# set the default Django settings module for the 'celery' program.
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'CORE.settings')

app = Celery('CORE')

# 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 app configs.
app.autodiscover_tasks()


@app.task(bind=True)
def debug_task(self):
    print('Request: {0!r}'.format(self.request))

cat/opt/project/CORE/CORE/init.py

from __future__ import absolute_import, unicode_literals

# This will make sure the app is always imported when
# Django starts so that shared_task will use this app.
from .celery import app as celery_app

__all__ = ('celery_app',)

cat /etc/supervisor/conf.d/celeryd.conf

; ==================================
;  Celery worker
; ==================================
; For additional options see http://supervisord.org/configuration.html#program-x-section-settings

[program:celery]

environment=
    PATH="/opt/data/project/bin:${PATH}",
    LD_LIBRARY_PATH="/opt/data/project/lib"
user=apache; change user nobody , root
directory=/opt/data/project/CORE
command=/opt/data/project/bin/celery worker -A CORE --loglevel=INFO --pidfile="/var/run/celery/celery.pid"
numprocs=1

; ***START OPTIONs***
autostart=true      ; Set it to "true" if you want supervisord to start service/script on system boot.
autorestart=true    ; Set it to "true" if you want supervisord to start service/script if it stops unexpectedly.
startsecs=10        ; The total number of seconds which the program needs to stay running after a startup to consider the start successful.
startretries=3      ; The number of retries to do before giving up trying to run service/script.
; ***LOGS***
stdout_logfile=/var/log/supervisor/%(program_name)s.log     ; The file where the errors will be written.
stderr_logfile=/var/log/supervisor/%(program_name)s_err.log ; The file where the regular outputs will be written.
;stderr_logfile_maxbytes=50     ; The maximum number of bytes that may be consumed by stderr_logfile before it is rotated
;stdout_logfile_maxbytes=50     ; The maximum number of bytes that may be consumed by stdout_logfile before it is rotated

; ***STOP OPTIONs***
stopasgroup=true

; Need to wait for currently executing tasks to finish at shutdown.
; Increase this if you have very long running tasks.
stopwaitsecs = 600

; ***PRIORITY***
; Set Celery priority higher than default (999)
; so, if rabbitmq is supervised, it will start first.
priority=1001        ; 999 -RabbitMq, 1000 -Redis, 1001 -Celery worker, 1002 -celery flower, etc...

проблема

RuntimeError: populate() isn't reentrant
Traceback (most recent call last):
  File "/opt/data/project/bin/celery", line 18, in <module>
    sys.exit(main())
  File "/opt/data/project/lib/python2.7/site-packages/celery/__main__.py", line 16, in main
    _main()
  File "/opt/data/project/lib/python2.7/site-packages/celery/bin/celery.py", line 322, in main
    cmd.execute_from_commandline(argv)
  File "/opt/data/project/lib/python2.7/site-packages/celery/bin/celery.py", line 496, in execute_from_commandline
    super(CeleryCommand, self).execute_from_commandline(argv)))
  File "/opt/data/project/lib/python2.7/site-packages/celery/bin/base.py", line 275, in execute_from_commandline
    return self.handle_argv(self.prog_name, argv[1:])
  File "/opt/data/project/lib/python2.7/site-packages/celery/bin/celery.py", line 488, in handle_argv
    return self.execute(command, argv)
  File "/opt/data/project/lib/python2.7/site-packages/celery/bin/celery.py", line 420, in execute
    ).run_from_argv(self.prog_name, argv[1:], command=argv[0])
  File "/opt/data/project/lib/python2.7/site-packages/celery/bin/worker.py", line 223, in run_from_argv
    return self(*args, **options)
  File "/opt/data/project/lib/python2.7/site-packages/celery/bin/base.py", line 238, in __call__
    ret = self.run(*args, **kwargs)
  File "/opt/data/project/lib/python2.7/site-packages/celery/bin/worker.py", line 257, in run
    **kwargs)
  File "/opt/data/project/lib/python2.7/site-packages/celery/worker/worker.py", line 96, in __init__
    self.app.loader.init_worker()
  File "/opt/data/project/lib/python2.7/site-packages/celery/loaders/base.py", line 119, in init_worker
    self.import_default_modules()
  File "/opt/data/project/lib/python2.7/site-packages/celery/loaders/base.py", line 112, in import_default_modules
    raise response
RuntimeError: populate() isn't reentrant

vi / opt / data / project / bin / celery

if __name__ == '__main__':
    file = open("/var/run/celery/testfile.txt","w")
    for o in os.environ:
        file.write(str(o)+'='+str(os.environ[o])+'\n')
    file.close()
    sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0])

vi /opt/data/project/lib/python2.7/site-packages/celery/loaders/base.py

   def import_default_modules(self):
        responses = signals.import_modules.send(sender=self.app)
        # Prior to this point loggers are not yet set up properly, need to
        #   check responses manually and reraised exceptions if any, otherwise
        #   they'll be silenced, making it incredibly difficult to debug.
        for _, response in responses:
            file = open("/var/run/celery/testfile.txt","ab")
            file.write("TEST: " + str(_) + ' ' + str(dir(response)) + '\n')
            file.close()
            if isinstance(response, Exception):
                raise response
        return [self.import_task_module(m) for m in self.default_modules]

cat /var/run/celery/testfile.txt

SUPERVISOR_SERVER_URL=unix:///tmp/supervisor.sock
SUPERVISOR_ENABLED=1
SUPERVISOR_PROCESS_NAME=celery
SUPERVISOR_GROUP_NAME=celery
_=/opt/data/project/bin/supervisord
SHLVL=2
LANG=en_US.UTF-8
PWD=/
PATH=/opt/data/project/bin:${PATH}
LD_LIBRARY_PATH=/opt/data/project/lib

TEST: <bound method ?.on_import_modules of <celery.fixups.django.DjangoFixup object at 0x7f2ac72ccb50>> ['__class__', '__delattr__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__']
TEST: <promise@0x7f2ac7383df8 --> <bound method Celery._autodiscover_tasks of <Celery CORE at 0x7f2ac72cca50>>> ['__class__', '__delattr__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__']

Вывод выше, когда все работает, когда я переключаюсь на пользователя, который не работаетЯ получаю точно такие же переменные среды, но «тестовая» часть отсутствует.Я пишу в файл в base.py перед "поднять ответ", поэтому что-то должно быть там, но на самом деле ничего нет.

...