2015-04-30 10 views
5

Ho una app Django servita con nginx + gunicorn con 3 processi di lavoro gunicorn. Occasionalmente (forse una volta ogni 100 richieste o giù di lì) uno dei processi di lavoro entra in uno stato in cui inizia a mancare la maggior parte (ma non tutte) le richieste che serve, e quindi genera un'eccezione quando tenta di inviarmi una e-mail. I registri degli errori gunicorn simile a questa:Come eseguire il debug degli errori intermittenti dall'app Django servita con gunicorn (possibile condizione di competizione)?

[2015-04-29 10:41:39 +0000] [20833] [ERROR] Error handling request 
Traceback (most recent call last): 
    File "/home/django/virtualenvs/homestead_django/local/lib/python2.7/site-packages/gunicorn/workers/sync.py", line 130, in handle 
    File "/home/django/virtualenvs/homestead_django/local/lib/python2.7/site-packages/gunicorn/workers/sync.py", line 171, in handle_request 
    File "/home/django/virtualenvs/homestead_django/local/lib/python2.7/site-packages/django/core/handlers/wsgi.py", line 206, in __call__ 
    File "/home/django/virtualenvs/homestead_django/local/lib/python2.7/site-packages/django/core/handlers/base.py", line 196, in get_response 
    File "/home/django/virtualenvs/homestead_django/local/lib/python2.7/site-packages/django/core/handlers/base.py", line 226, in handle_uncaught_exception 
    File "/usr/lib/python2.7/logging/__init__.py", line 1178, in error 
    File "/usr/lib/python2.7/logging/__init__.py", line 1271, in _log 
    File "/usr/lib/python2.7/logging/__init__.py", line 1281, in handle 
    File "/usr/lib/python2.7/logging/__init__.py", line 1321, in callHandlers 
    File "/usr/lib/python2.7/logging/__init__.py", line 749, in handle 
    File "/home/django/virtualenvs/homestead_django/local/lib/python2.7/site-packages/django/utils/log.py", line 122, in emit 
    File "/home/django/virtualenvs/homestead_django/local/lib/python2.7/site-packages/django/utils/log.py", line 125, in connection 
    File "/home/django/virtualenvs/homestead_django/local/lib/python2.7/site-packages/django/core/mail/__init__.py", line 29, in get_connection 
    File "/home/django/virtualenvs/homestead_django/local/lib/python2.7/site-packages/django/utils/module_loading.py", line 26, in import_by_path 
    File "/home/django/virtualenvs/homestead_django/local/lib/python2.7/site-packages/django/utils/module_loading.py", line 21, in import_by_path 
    File "/home/django/virtualenvs/homestead_django/local/lib/python2.7/site-packages/django/utils/importlib.py", line 40, in import_module 
ImproperlyConfigured: Error importing module django.core.mail.backends.smtp: "No module named smtp" 

Così alcuni eccezione non identificata sta accadendo e poi Django sta cercando di scrivermi a questo proposito. Il fatto che non possa importare django.core.mail.backends.smtp non ha senso perché django.core.mail.backends.smtp deve essere sicuramente sul percorso Python del processo di lavoro. Posso importarlo bene da un manage.py shell e ricevo e-mail per altri errori del server (veri e propri bug del software) quindi so che funziona. È come se l'ambiente del processo di lavoro fosse corrotto in qualche modo.

Una volta che un processo di lavoro entra in questo stato, è molto difficile riprendersi; quasi ogni richiesta che serve finisce per fallire in questo stesso modo. Se ricomincio gunicorn, tutto va bene (fino a quando un altro processo di lavoro ricade nuovamente in questo stato strano).

Non noto alcuno schema ovvio, quindi non penso che questo sia stato innescato da un bug nella mia app (l'errore degli URL è diverso, ecc.). Sembra una specie di condizione di gara.

Attualmente sto usando l'opzione gunicorn--max-requests per mitigare questo problema ma mi piacerebbe capire cosa sta succedendo qui. Questa è una condizione di gara? Come posso eseguire il debug di questo?

+1

Sei a corto di risorse/RAM? Ho notato nei documenti di gunicorn per '--max-requests' che dice *" Qualsiasi valore maggiore di zero limiterà il numero di richieste che un lavoro elaborerà prima del riavvio automatico.Questo è un metodo semplice per aiutare a limitare il danno della memoria perdite. "* Che potrebbe descrivere il motivo per cui questo sembra risolvere il problema - potresti avere una perdita di memoria da qualche parte (o semplicemente usare troppa memoria) –

+0

Quale versione di Django stai usando? –

+0

@ TimmyO'Mahony Ho ancora diverse centinaia di MB di RAM e l'utilizzo della memoria non aumenta nel tempo, quindi non penso che sia una perdita ... Lo esaminerò di nuovo però. – mgalgs

risposta

0

Abbiamo scoperto una vista particolare che stava bloccando la CPU per alcuni secondi ogni volta che veniva caricato che sembrava provocare il problema. Non riesco ancora a capire in che modo sbattere un dipendente di gunicorn possa causare un ambiente di esecuzione corrotto, ma risolvere il problema della visualizzazione della CPU elevata sembra essersi risolto.

0

Ti suggerisco di usare Sentry che offre un modo intelligente di gestire gli errori.

È possibile utilizzarlo come soluzione basata su cloud (getsentry) oppure è possibile installarlo sul proprio server (github).

Prima di utilizzare il mailer del registro core di django ora uso sempre la sentinella.

Non lavoro a Sentry ma la loro soluzione è davvero fantastica!

Problemi correlati