Назад | Перейти на главную страницу

Ответы Nginx uWSGI усечены

Я пытался написать веб-сервис в шутку сегодня на http://dont-tread-on-memes.controversial.io. Это приложение-фляга, которое обслуживает довольно большие изображения. Приложение Flask хорошо работает само по себе, как и независимый сервер uWSGI, но когда я пытаюсь подключить uWSGI к NGINX через uwsgi_pass, внезапно все остальные запросы в браузерах обрезаются до 9,99 КБ.

Прочитав про подобное усечение с proxy_pass Я попытался:

  1. Настройка uwsgi_buffering к off в моем файле конфигурации
  2. Увеличение размера буфера до 1024k с участием uwsgi_buffers 1024 1024k; uwsgi_buffer_size 1024k;
  3. sendfile: off
  4. Проверка прав доступа к буферному файлу (все файлы в /var/lib/uwsgi принадлежат www-data пользователь и www-data group, поэтому я считаю, что у меня хорошие разрешения.)

Я остался с моей текущей конфигурацией, в которой все еще есть проблема:

server {
    listen 80;
    server_name dont-tread-on-memes.controversial.io;

    location / {
        include uwsgi_params;
        uwsgi_pass unix:/var/www/dont-tread-on-memes/dont_tread_on_memes.sock;
        uwsgi_buffers 1024 1024k;
        uwsgi_buffer_size 1024k;
    }
}

Самое странное, что эта проблема появляется только при каждом втором запросе. Это должно быть связано с кешем NGINX, поскольку я не использую несколько экземпляров NGINX или что-то еще. Тем не менее, это должно быть связано с моей конфигурацией NGINX, поскольку uWSGI, работающий сам по себе, не обнаруживает проблемы.

Есть мысли о том, что может вызвать эту проблему и как ее исправить?

Это почти всегда означает, что есть проблема с вашими изображениями (то есть в нижней части отсутствуют данные). Я обработал изображения размером> 25 МБ с использованием PIL (при условии, что у вас достаточно оперативной памяти), и он отлично работает. В обходной путь здесь может сработать для вас. Скопируйте и вставьте для удобства чтения:

if img and img.meta_type == 'Image':
    pilImg = PIL.Image.open( StringIO(str(img.data)) )
elif imgData:
    pilImg = PIL.Image.open( StringIO(imgData) )

try:
    pilImg.load()
except IOError:
    pass # You can always log it to logger

После двойной проверки, что uwsgi команда, которую я тестировал, соответствовала всем параметрам, указанным в моем .ini файл, я понял, что мой .ini файл содержал processes = 5 в то время uwsgi Команда, с которой я тестировал, этого не сделала. Если я добавлю --processes=5 к моему uwsgi команду, я могу воспроизвести проблему усечения на каждый попадание, а не только на каждый второй запрос. Каждый раз, когда я запускаю uwsgi сервер с --processes=5, первый запрос завершается успешно, второй возвращает 500, а все последующие запросы обрезаются до 9,99 МБ со следующей ошибкой в ​​консоли:

[2017-01-08 04:16:08,959] ERROR in app: Exception on / [GET]
Traceback (most recent call last):
  File "/usr/local/lib/python3.4/dist-packages/flask/app.py", line 1982, in wsgi_app
    response = self.full_dispatch_request()
  File "/usr/local/lib/python3.4/dist-packages/flask/app.py", line 1614, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "/usr/local/lib/python3.4/dist-packages/flask/app.py", line 1517, in handle_user_exception
    reraise(exc_type, exc_value, tb)
  File "/usr/local/lib/python3.4/dist-packages/flask/_compat.py", line 33, in reraise
    raise value
  File "/usr/local/lib/python3.4/dist-packages/flask/app.py", line 1612, in full_dispatch_request
    rv = self.dispatch_request()
  File "/usr/local/lib/python3.4/dist-packages/flask/app.py", line 1598, in dispatch_request
    return self.view_functions[rule.endpoint](**req.view_args)
  File "./flaskapp.py", line 13, in main
    flag = dont_tread_on_memes.dont_me(caption)
  File "./dont_tread_on_memes/__init__.py", line 30, in dont_me
    return tread_on("don't {} me".format(phrase))
  File "./dont_tread_on_memes/__init__.py", line 16, in tread_on
    flag = BLANK_FLAG.copy()
  File "/usr/local/lib/python3.4/dist-packages/PIL/Image.py", line 1010, in copy
    self.load()
  File "/usr/local/lib/python3.4/dist-packages/PIL/ImageFile.py", line 226, in load
    "(%d bytes not processed)" % len(b))
OSError: image file is truncated (0 bytes not processed)

Я подозреваю, что это проблема с подушкой и способом uwsgi обрабатывает резьбу. Возможно, поведение любого другого запроса было связано с тем, как uwsgi решает порождать новые процессы и уничтожать старые процессы, или из-за кеширования NGINX. В любом случае я исправил проблему с усечением.

Я также нашел этот на StackOverflow от кого-то с моей проблемой.

Если кто-то еще может дать ответ, почему это произошло, или ответ о том, как я могу решить эту проблему и позволить uwsgi порождают несколько процессов, я бы, конечно, посчитал это более полным ответом и принял его.