2015-02-22 3 views
3

Я столкнулся со странной ошибкой, которая прерывистая и трудная для отслеживания. Одна из страниц моего сайта, работающего на django, позволяет пользователям загружать музыку, которую они приобрели.Ошибка сегментации uWSGI и Django

Проблема: Некоторые пользователи сообщают о ошибке 502 при загрузке. Дальнейшее исследование проблемы показывает, что в uWSGI существует ошибка сегментации. Я действительно не знаю, как отлаживать это, и я ищу все, что может помочь найти разрешение.

Попытки решить эту проблему:
Я думал, что это может быть, что я бегу слишком много процессов uWSGI, поэтому я опустил, но так как проблема происходит только иногда (некоторые пользователи не имеют никаких проблем, некоторые повторите попытку с успехом), я не могу быть уверен, что ошибка решена.

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

Следующие шаги:
Я ищу некоторые рекомендации по этому вопросу, или какие-либо идеи о том, как я могу получить немного больше информации о том, что происходит здесь.

uWSGI конфигурации:

[uwsgi] 
plugin=/etc/uwsgi/python_plugin.so 
wsgi-file   = /path/to/my/project/projectname/wsgi.py 
home    = /path/to/my/project/ 
master    = true 
socket    = /tmp/uwsgi.sock 
chmod-socket  = 666 
vacuum    = true 
processes   = 3 
workers    = 15 
min-worker-lifetime = 45 
max-requests  = 100 
reload-mercy  = 5 
harakiri   = 20 
buffer-size   = 16384 

Соответствующий вид:

def zipForDownload(album): 

    bonus = BonusContent.objects.filter(album=album) 
    bonus_files = [open(f.bonus_file.path, 'rb') for f in bonus] 

    tracks = trackSort(list(Track.objects.filter(album=album))) 
    track_files = [open(f.audio_file.path, 'rb') for f in tracks] 


    zipped_file = StringIO.StringIO() 
    with zipfile.ZipFile(zipped_file, 'w') as zip: 
     for i, f in enumerate(track_files): 
      f.seek(0) 
      num = tracks[i].track_number 
      name = tracks[i].name 
      ext = os.path.basename(f.name).split('.')[-1] 
      zip.writestr("{0} - {1}.{2}".format(num, name, ext), f.read()) 
     for i, f in enumerate(bonus_files): 
      name = bonus[i].name 
      ext = os.path.basename(f.name).split('.')[-1] 
      zip.writestr("{0}.{1}".format(name, ext), f.read()) 

    zipped_file.seek(0) 
    response = HttpResponse(zipped_file, content_type='application/octet-stream') 
    response['Content-Disposition'] = 'attachment; filename=%s.zip' % (album.name) 
    return response 

def downloadPostPin(request, purchase): 
    if request.POST.get('PIN').encode('utf-8') == purchase.download_pin.encode('utf-8'): 
     # Get zip response with all tracks and bonus content 
     resp = zipForDownload(purchase.album) 
     return resp 

    else: 
     # Otherwise, return the same page again with an error 
     error = "Invalid PIN. Please try again!" 
     return downloadPrePin(request, purchase, error) 

uWSGI журнал ошибок:

!!! uWSGI process 8094 got Segmentation Fault !!! 
*** backtrace of 8094 *** 
/home/web/.envs/music/bin/uwsgi(uwsgi_backtrace+0x2e) [0x46a1be] 
/home/web/.envs/music/bin/uwsgi(uwsgi_segfault+0x21) [0x46a581] 
/lib/x86_64-linux-gnu/libc.so.6(+0x36c30) [0x7fdc1ffd6c30] 
/usr/lib/x86_64-linux-gnu/libpython2.7.so.1.0(PyObject_Malloc+0x248) [0x7fdc206ef508] 
/usr/lib/x86_64-linux-gnu/libpython2.7.so.1.0(PyString_FromStringAndSize+0xa2) [0x7fdc206de232] 
/usr/lib/x86_64-linux-gnu/libpython2.7.so.1.0(PyEval_EvalFrameEx+0x3be7) [0x7fdc206fe0e7] 
/usr/lib/x86_64-linux-gnu/libpython2.7.so.1.0(PyEval_EvalCodeEx+0x80d) [0x7fdc2070117d] 
/usr/lib/x86_64-linux-gnu/libpython2.7.so.1.0(PyEval_EvalFrameEx+0x48d8) [0x7fdc206fedd8] 
/usr/lib/x86_64-linux-gnu/libpython2.7.so.1.0(PyEval_EvalCodeEx+0x80d) [0x7fdc2070117d] 
/usr/lib/x86_64-linux-gnu/libpython2.7.so.1.0(+0x162310) [0x7fdc20701310] 
/usr/lib/x86_64-linux-gnu/libpython2.7.so.1.0(PyObject_Call+0x43) [0x7fdc206c8e23] 
/usr/lib/x86_64-linux-gnu/libpython2.7.so.1.0(+0x7d30d) [0x7fdc2061c30d] 
/usr/lib/x86_64-linux-gnu/libpython2.7.so.1.0(PyObject_Call+0x43) [0x7fdc206c8e23] 
/usr/lib/x86_64-linux-gnu/libpython2.7.so.1.0(PyEval_CallObjectWithKeywords+0x47) [0x7fdc20687837] 
/usr/lib/x86_64-linux-gnu/libpython2.7.so.1.0(+0xff706) [0x7fdc2069e706] 
/usr/lib/x86_64-linux-gnu/libpython2.7.so.1.0(PyEval_EvalFrameEx+0x2920) [0x7fdc206fce20] 
/usr/lib/x86_64-linux-gnu/libpython2.7.so.1.0(+0x161883) [0x7fdc20700883] 
/usr/lib/x86_64-linux-gnu/libpython2.7.so.1.0(+0x1a7d02) [0x7fdc20746d02] 
/usr/lib/x86_64-linux-gnu/libpython2.7.so.1.0(PySequence_List+0x2c) [0x7fdc207471bc] 
/usr/lib/x86_64-linux-gnu/libpython2.7.so.1.0(PySequence_Fast+0x3d) [0x7fdc2074807d] 
/usr/lib/x86_64-linux-gnu/libpython2.7.so.1.0(+0x1aa995) [0x7fdc20749995] 
/usr/lib/x86_64-linux-gnu/libpython2.7.so.1.0(PyEval_EvalFrameEx+0x4abc) [0x7fdc206fefbc] 
/usr/lib/x86_64-linux-gnu/libpython2.7.so.1.0(PyEval_EvalCodeEx+0x80d) [0x7fdc2070117d] 
/usr/lib/x86_64-linux-gnu/libpython2.7.so.1.0(+0x162310) [0x7fdc20701310] 
/usr/lib/x86_64-linux-gnu/libpython2.7.so.1.0(PyObject_Call+0x43) [0x7fdc206c8e23] 
/usr/lib/x86_64-linux-gnu/libpython2.7.so.1.0(PyObject_CallFunction+0xbb) [0x7fdc20706efb] 
/usr/lib/x86_64-linux-gnu/libpython2.7.so.1.0(+0x16a15d) [0x7fdc2070915d] 
/usr/lib/x86_64-linux-gnu/libpython2.7.so.1.0(_PyObject_GenericSetAttrWithDict+0x107) [0x7fdc205f00b7] 
/usr/lib/x86_64-linux-gnu/libpython2.7.so.1.0(PyObject_SetAttr+0x8f) [0x7fdc206aeadf] 
/usr/lib/x86_64-linux-gnu/libpython2.7.so.1.0(PyEval_EvalFrameEx+0x1cda) [0x7fdc206fc1da] 
/usr/lib/x86_64-linux-gnu/libpython2.7.so.1.0(PyEval_EvalCodeEx+0x80d) [0x7fdc2070117d] 
/usr/lib/x86_64-linux-gnu/libpython2.7.so.1.0(+0x1623e5) [0x7fdc207013e5] 
/usr/lib/x86_64-linux-gnu/libpython2.7.so.1.0(PyObject_Call+0x43) [0x7fdc206c8e23] 
/usr/lib/x86_64-linux-gnu/libpython2.7.so.1.0(+0x7d30d) [0x7fdc2061c30d] 
/usr/lib/x86_64-linux-gnu/libpython2.7.so.1.0(PyObject_Call+0x43) [0x7fdc206c8e23] 
/usr/lib/x86_64-linux-gnu/libpython2.7.so.1.0(+0x12e48f) [0x7fdc206cd48f] 
/usr/lib/x86_64-linux-gnu/libpython2.7.so.1.0(+0x12c4df) [0x7fdc206cb4df] 
/usr/lib/x86_64-linux-gnu/libpython2.7.so.1.0(PyObject_Call+0x43) [0x7fdc206c8e23] 
/usr/lib/x86_64-linux-gnu/libpython2.7.so.1.0(PyEval_EvalFrameEx+0x2316) [0x7fdc206fc816] 
/usr/lib/x86_64-linux-gnu/libpython2.7.so.1.0(PyEval_EvalFrameEx+0x4b59) [0x7fdc206ff059] 
/usr/lib/x86_64-linux-gnu/libpython2.7.so.1.0(PyEval_EvalFrameEx+0x4b59) [0x7fdc206ff059] 
/usr/lib/x86_64-linux-gnu/libpython2.7.so.1.0(PyEval_EvalCodeEx+0x80d) [0x7fdc2070117d] 
/usr/lib/x86_64-linux-gnu/libpython2.7.so.1.0(+0x1623e5) [0x7fdc207013e5] 
/usr/lib/x86_64-linux-gnu/libpython2.7.so.1.0(PyObject_Call+0x43) [0x7fdc206c8e23] 
/usr/lib/x86_64-linux-gnu/libpython2.7.so.1.0(PyEval_EvalFrameEx+0xeb1) [0x7fdc206fb3b1] 
/usr/lib/x86_64-linux-gnu/libpython2.7.so.1.0(PyEval_EvalCodeEx+0x80d) [0x7fdc2070117d] 
/usr/lib/x86_64-linux-gnu/libpython2.7.so.1.0(PyEval_EvalFrameEx+0x48d8) [0x7fdc206fedd8] 
/usr/lib/x86_64-linux-gnu/libpython2.7.so.1.0(PyEval_EvalCodeEx+0x80d) [0x7fdc2070117d] 
/usr/lib/x86_64-linux-gnu/libpython2.7.so.1.0(+0x162310) [0x7fdc20701310] 
/usr/lib/x86_64-linux-gnu/libpython2.7.so.1.0(PyObject_Call+0x43) [0x7fdc206c8e23] 
/usr/lib/x86_64-linux-gnu/libpython2.7.so.1.0(+0x7d30d) [0x7fdc2061c30d] 
/usr/lib/x86_64-linux-gnu/libpython2.7.so.1.0(PyObject_Call+0x43) [0x7fdc206c8e23] 
/usr/lib/x86_64-linux-gnu/libpython2.7.so.1.0(+0x12e5f5) [0x7fdc206cd5f5] 
/usr/lib/x86_64-linux-gnu/libpython2.7.so.1.0(PyObject_Call+0x43) [0x7fdc206c8e23] 
/usr/lib/x86_64-linux-gnu/libpython2.7.so.1.0(PyEval_CallObjectWithKeywords+0x47) [0x7fdc20687837] 
/home/web/.envs/music/bin/uwsgi(python_call+0x11) [0x4808a1] 
/home/web/.envs/music/bin/uwsgi(uwsgi_request_wsgi+0x116) [0x482a96] 
/home/web/.envs/music/bin/uwsgi(wsgi_req_recv+0xa2) [0x41f1f2] 
/home/web/.envs/music/bin/uwsgi(simple_loop_run+0xc4) [0x466664] 
/home/web/.envs/music/bin/uwsgi(uwsgi_ignition+0x194) [0x46a7d4] 
/home/web/.envs/music/bin/uwsgi(uwsgi_worker_run+0x2dd) [0x46f02d] 
/home/web/.envs/music/bin/uwsgi(uwsgi_run+0x3b4) [0x46f554] 
/home/web/.envs/music/bin/uwsgi(_start+0) [0x41e8ae] 
/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xf5) [0x7fdc1ffc1ec5] 
*** end of backtrace *** 
DAMN ! worker 9 (pid: 8094) died :(trying respawn ... 
Respawned uWSGI worker 9 (new pid: 8371) 

ответ

3

Проблема происходит потому, что ваш процесс не может выделить блок памяти.

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

zip.writestr("{0} - {1}.{2}".format(num, name, ext), f.read()) 

f.read() здесь будет читать все содержимое файла все сразу и положить, что в памяти, то будет пытаться записать его в другой раздел памяти, StringIO объект, который, в свою очередь, в конечном итоге хранения же данные дважды в разных частях ОЗУ.

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

for i, f in enumerate(track_files): 
    f.seek(0) 
    ... 
    while True: 
     data = f.read(2**16) 
     if not data: 
      break 
     else: 
      zip.write(data) 
    ... 
    f.close() 

Возможно, вы захотите взглянуть на this SO answer о написании куска экземпляра размером zipfile.ZipFile.

+0

Красивые. Спасибо за предоставление такого полного ответа. –

Смежные вопросы