2015-02-23 25 views
10

ustawić zmienną środowiskową w supervisord:Python Key Błąd przy ustawianiu zmiennej środowiskowej w supervisord

[program:worker] 
directory = /srv/app/ 
command=celery -A tasks worker -Q default -l info -n default_worker.%%h 
environment=BROKER="amqp://admin:[email protected]:5672//" 

ciągu mojego celeryconfig.py I spróbuj czytać tej zmiennej takiego.

BROKER = os.environ['BROKER'] 

Ale nadal otrzymuję klucz poniżej, dlaczego?

File "/usr/local/lib/python2.7/dist-packages/celery/loaders/base.py", line 106, in import_module 
    return importlib.import_module(module, package=package) 
    File "/usr/lib/python2.7/importlib/__init__.py", line 37, in import_module 
    __import__(name) 
    File "/srv/app/celeryconfig.py", line 6, in <module> 
    BROKER = os.environ['BROKER'] 
    File "/usr/lib/python2.7/UserDict.py", line 23, in __getitem__ 
    raise KeyError(key) 
KeyError: 'BROKER 

Jest wysypisko plik z envs jak zasugerowano w komentarzach:

{ 
    'SUPERVISOR_GROUP_NAME': 'celery_default_worker', 
    'TERM': 'linux', 
    'SUPERVISOR_SERVER_URL': 'unix: ///var/run/supervisor.sock', 
    'UPSTART_INSTANCE': '', 
    'RUNLEVEL': '2', 
    'UPSTART_EVENTS': 'runlevel', 
    'PREVLEVEL': 'N', 
    'SUPERVISOR_PROCESS_NAME': 'celery_default_worker', 
    'UPSTART_JOB': 'rc', 
    'PWD': '/', 
    'SUPERVISOR_ENABLED': '1', 
    'runlevel': '2', 
    'PATH': '/usr/local/sbin: /usr/local/bin: /sbin: /bin: /usr/sbin: /usr/bin', 
    'previous': 'N' 
} 
+1

Dziwne - to wygląda poprawnie w pierwszym przejściu. Być może pomoże to w debugowaniu dodać 'with open ("/tmp/selery-environment.txt "," w ") jako f: f.write (repr (os.environ))' do twojego 'celeryconfig.py', następnie sprawdzając plik '/ tmp/seler-environment.txt', aby zobaczyć, co * oznacza * w twoim środowisku? –

+0

Potwierdź kolejność wykonywania. tj. sprawdź, czy zmienna środowiskowa BROKER jest ustawiona jako pierwsza w 'supervisord:' lub BROKER jest odczytywana jako pierwsza w 'CeleryConfig.py'. Jeśli najpierw przeczyta się 'CeleryConfig.py', to BROKER nie istnieje, ponieważ BROKER jest ustawiony w' supervisord: ' – Vinkal

+0

Czy powiedziałeś' supervisordowi ', aby podniósł zmiany, lub w inny sposób ponownie uruchomił 'supervisord'? –

Odpowiedz

2

Ta odpowiedź jest najprawdopodobniej nie przyczyna, sprawdź https://stackoverflow.com/a/28829162/1589147 uzyskać informacje o pokrewnej supervisord bug zamiast.

Mogę częściowo powielić Twój błąd. Nie widzę błędu, gdy seler porusza się w superwizorze. Widzę błąd, gdy próbuję uruchomić zadanie ze środowiska zewnętrznego, gdzie nie ustawiłem zmiennej środowiskowej BROKER. celeryconfig.py jest wykonywany zarówno przez seler, jak i przez wszystko, co próbuje wykonać zadanie.

Nie jestem pewien, czy ten problem jest dokładnie tym, na co natknąłeś się, czy możesz podzielić się tym, jak wykonujesz zadania, a kiedy ten wyjątek zostanie podniesiony, może pomóc.

Na przykład, jeśli spróbuję uruchomić zadanie od ipython, zostanie wygenerowany błąd odpowiadający błędowi.

In [1]: from tasks import add 
In [2]: add.delay(2,3) 
... 
    21   if hasattr(self.__class__, "__missing__"): 
    22    return self.__class__.__missing__(self, key) 
---> 23   raise KeyError(key) 
    24  def __setitem__(self, key, item): self.data[key] = item 
    25  def __delitem__(self, key): del self.data[key] 

KeyError: 'BROKER' 

The celeryconfig.py jest ładowany na miejscu, w celu ustanowienia połączenia z maklera selera i backend. Nie mogę wykonać zadania bez ustawienia zmiennej środowiskowej BROKER.

Jeśli ustawię zmienną środowiskową przed wykonaniem zadania, ten sam kod działa dla mnie.

In [3]: import os 
In [4]: os.environ["BROKER"] = "broker is set" 
In [5]: add.delay(2,3) 
Out[5]: <AsyncResult: 0f3xxxx-87fa-48d7-9258-173bdd2052ca> 

Oto pliki, których użyłem na wypadek, gdyby to pomogło.

supervisor.conf: supervisord -c supervisor.conf

[unix_http_server] 
file=/tmp/supervisor.sock 

[supervisord] 
loglevel = info 
nodaemon = true 
identifier = supervisor 

[supervisorctl] 
serverurl=unix:///tmp/supervisor.sock 

[rpcinterface:supervisor] 
supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface 

[program:worker] 
command=/app/srv/main-env/bin/celery -A tasks worker -Q default -l info -n default_worker.%%h 
environment=BROKER="amqp://admin:[email protected]:5672//" 
directory=/app/srv/ 
numprocs=1 
stdout_logfile=/app/srv/worker.log 
stderr_logfile=/app/srv/worker.log 
autostart=true 
autorestart=true 
startsecs=10 
stopwaitsecs = 600 
killasgroup=true 
priority=998 

celeryconfig.py:

import os 


BROKER = os.environ['BROKER'] 

tasks.py:

from celery import Celery 

app = Celery(
    'tasks', 
    backend='amqp', 
    broker='amqp://admin:[email protected]:5672//') 
app.config_from_object('celeryconfig') 


@app.task 
def add(x, y): 
     return x + y 
+0

Wygląda na to, że 'supervisord' nie może zastosować zmiennych środowiskowych podprocesu. –

+0

Myślę, że błędy, o których wspomniałeś, są bardziej prawdopodobną przyczyną zgłoszonego błędu niż moja odpowiedź, ponieważ środowisko, które wyświetlają, pokazuje liczne zmienne środowiskowe ustawione przez supervisora. Czy mógłbyś opublikować swój komentarz jako odpowiedź, aby go upomnieć? –

+0

done (.filler.) –

6

Wygląda na to znany błąd w supervisord:

http://github.com/Supervisor/supervisor/issues/91 (kindof rozwiązany)

http://github.com/Supervisor/supervisor/pull/550 (w toku)

W takim przypadku ruch specyfikację środowiskową do zasięgu globalnym (dla samego procesu supervisord) może być do zaakceptowania obejście.

Na koniec, jeśli wszystko inne zawiedzie, zawiń celery w skrypcie powłoki, który akceptuje tę określoną zmienną środowiskową jako argument wiersza poleceń.