2013-03-15 9 views
5

Próbuję debugować rzadkie zawieszenie aplikacji Django. Do tej pory nie udało mi się wyizolować problem, zdarza się raz dziennie w produkcji i Gunicorn restartuje proces z komunikatem:Zrzut Dump Django na limicie czasu Gunicorn

[CRITICAL] WORKER TIMEOUT 

Czy istnieje sposób, aby skonfigurować Django lub Gunicorn zrzucić ślad stosu procesu to jest zrestartowane?

Odpowiedz

5

Spróbuj ustawić swój dziennik Gunicorn jako bardziej szczegółowy, może ustawić go na INFO lub DEBUG, który może rzucić więcej światła w dzienniku.

Można również obejrzeć Dog Slow, który będzie rejestrował powolne żądania. https://pypi.python.org/pypi/dogslow.

Aby wygrać z ogólnym logowaniem, spróbuj użyć Sentry: https://www.getsentry.com/welcome/.

Losowe pytanie, jakieś crony na serwerze działającym w tym czasie, kopie zapasowe, coś w tym stylu?

+0

Dog Powolne wygląda świetnie, mogę ustawić jej limit czasu być trochę niższa niż limit czasu Gunicorn i uzyskać ślad zamkniętym procesie. Dzięki! Działa na Heroku, więc nie powinno być żadnych ciężkich procesów w tle. –

0

Limit czasu nie jest przeznaczony jako limit czasu żądania. Ma to na celu sprawdzenie życia pracowników. W przypadku pracowników synchronizacji działa to jako limit czasu żądania, ponieważ pracownik nie może wykonać niczego poza przetworzeniem żądania. Asynchroniczne bicie pulsu pracowników, nawet gdy obsługują one długo działające żądania, więc dopóki pracownik nie zablokuje/nie zamrozi, nie zostanie zabity.

Gunicorn ma funkcję o nazwie worker_abort (patrz dokumentacja gunicorn poniżej).

def worker_abort(worker): 
    worker.log.info("worker received abort signal") 
    import threading, sys, traceback 
    id2name = dict([(th.ident, th.name) for th in threading.enumerate()]) 
    code = [] 
    for threadId, stack in sys._current_frames().items(): 
     code.append("\n# Thread: %s(%d)" % (id2name.get(threadId,""), threadId)) 
     stack = traceback.extract_stack(stack) 
     for filename, lineno, name, line in stack: 
      code.append('File: "%s", line %d, in %s' % (filename, lineno, name)) 
      if line: 
       code.append(" %s" % (line.strip())) 
    worker.log.debug("\n".join(code)) 

Wywoływany, gdy pracownik odebrał sygnał SIGABRT. To połączenie zwykle dzieje się po upływie limitu czasu. Podpowiedź musi zaakceptować jedną zmienną instancji dla zainicjowanego Pracownika.

Źródła:

http://docs.gunicorn.org/en/stable/settings.html, https://github.com/benoitc/gunicorn/issues/1493, https://github.com/benoitc/gunicorn/blob/master/examples/example_config.py