Сброшено соединение Nginx, потерян ответ от uWsgi

У меня есть приложение django, размещенное через Nginx и uWsgi. В одном очень простом запросе я получаю различное поведение для GET и POST, чего быть не должно.

Журнал демона uWsgi:

[pid: 32454|app: 0|req: 5/17] 127.0.0.1 () {36 vars in 636 bytes} [Tue Oct 19 11:18:36 2010] POST /buy/76d4f520ae82e1dfd35564aed64a885b/a_2/10/ => generated 80 bytes in 3 msecs (HTTP/1.0 440) 1 headers in 76 bytes (0 async switches on async core 0)
[pid: 32455|app: 0|req: 5/18] 127.0.0.1 () {32 vars in 521 bytes} [Tue Oct 19 11:18:50 2010] GET /buy/76d4f520ae82e1dfd35564aed64a885b/a_2/10/ => generated 80 bytes in 3 msecs (HTTP/1.0 440) 1 headers in 76 bytes (0 async switches on async core 0)

Журнал доступа Nginx:

127.0.0.1 - - [19/Oct/2010:18:18:36 +0200] "POST /buy/76d4f520ae82e1dfd35564aed64a885b/a_2/10/ HTTP/1.0" 440 0 "-" "curl/7.19.5 (i486-pc-linux-gnu) libcurl/7.19.5 OpenSSL/0.9.8g zlib/1.2.3.3 libidn/1.15"
127.0.0.1 - - [19/Oct/2010:18:18:50 +0200] "GET /buy/76d4f520ae82e1dfd35564aed64a885b/a_2/10/ HTTP/1.0" 440 80 "-" "curl/7.19.5 (i486-pc-linux-gnu) libcurl/7.19.5 OpenSSL/0.9.8g zlib/1.2.3.3 libidn/1.15"

Журнал ошибок Nginx:

2010/10/19 18:18:36 [error] 4615#0: *5 readv() failed (104: Connection reset by peer) while reading upstream, client: 127.0.0.1, server: localhost, request: "POST /buy/76d4f520ae82e1dfd35564aed64a885b/a_2/10/ HTTP/1.0", upstream: "uwsgi://unix:sock/uwsgi.sock:", host: "localhost:9201"

По сути, Nginx где-то теряет ответ, если я использую POST, но не так, если я использую GET.

Кто-нибудь что-нибудь знает об этом?


person Ulf    schedule 19.10.2010    source источник
comment
См. также stackoverflow.com/questions/7273725/   -  person Joe Shaw    schedule 07.09.2012


Ответы (4)


Передать --post-buffering 1 в uwsgi

Это автоматически буферизует все тело http> 1 байт

Проблема возникает из-за того, как nginx управляет отключением восходящего потока.

person roberto    schedule 25.02.2011
comment
FWIW, @roberto — автор uwsgi. - person Joe Shaw; 07.09.2012
comment
Это действительно правильный ответ. Это опция uwsgi, и вы, вероятно, захотите использовать ее вместе с --limit-post. projects.unbit.it/uwsgi/wiki/Doc - person Derrick Petzold; 22.09.2012
comment
У меня похожая проблема (только она не имеет ничего общего с POST). Пробовал пост-буферизацию, а также ForcePostHandler @ehabkost, но не повезло. Это сводит меня с ума, пожалуйста, помогите!!! stackoverflow.com/questions/18667370/ - person Tony Lâmpada; 08.09.2013
comment
Не бери в голову! Мне удалось решить проблему, добавив buffer-size = 8192 в uwsgi. Боже, как трудно было понять... - person Tony Lâmpada; 08.09.2013
comment
Однако не будет ли это большой проблемой производительности? В документе uWSGI говорится, что это сохранит все тело HTTP больше указанного предела. Сохранение тела на диск для каждого запроса POST может быть проблемой. - person John Smith Optional; 09.08.2014

Я столкнулся с той же проблемой, но в моем случае я не могу отключить «uwsgi_pass_request_body», так как в большинстве случаев (но не всегда) моему приложению нужны данные POST.

Это обходной путь, который я нашел, хотя эта проблема не устранена в uwsgi: http://permalink.gmane.org/gmane.comp.python.wsgi.uwsgi.general/813

import django.core.handlers.wsgi
class ForcePostHandler(django.core.handlers.wsgi.WSGIHandler):
    """Workaround for: http://lists.unbit.it/pipermail/uwsgi/2011-February/001395.html
    """
    def get_response(self, request):
        request.POST # force reading of POST data
        return super(ForcePostHandler, self).get_response(request)

application = ForcePostHandler()
person ehabkost    schedule 18.02.2011
comment
Это действительно сработало и для меня (в моем случае с проектом Flask). В основном вам нужно прочитать POST, прежде чем отвечать. - person Victor Farazdagi; 03.09.2011
comment
@VictorFarazdagi, как ты сделал это в Flask? - person Jarek; 05.11.2011
comment
Вот как я только что сделал, чтобы обойти эту неприятную проблему: response.data - person Khorkrak; 18.07.2012
comment
Ответ @roberto правильный. В противном случае большие POST-файлы будут храниться в памяти, а не буферизоваться на диск. - person Derrick Petzold; 22.09.2012

Я сталкиваюсь с теми же проблемами. Я пробовал все решения выше, но они не работали. Игнорировать тело ответа в моем случае просто не вариант.

По-видимому, это ошибка с nginx и uwsgi при обработке POST-запросов, ответ которых меньше 4052 байт.

Для меня это решило добавление «--pep3333-input» в список параметров uwsgi. После этого все POST возвращаются корректно.

Версии nginx/uwsgi, которые я использую:

$ nginx -V
nginx: nginx version: nginx/0.9.6

$ uwsgi --version
uWSGI 0.9.7
person lullis    schedule 12.06.2011
comment
Спасибо за ответ. Просто добавление --pep3333-input в uwsgi не помогло. Мне также пришлось добавить --post-buffering 4096, как указано здесь: comments.gmane.org/gmane.comp.python.wsgi.uwsgi.general/812 - person freb; 09.03.2012
comment
По словам Роберто, --pep3333-input теперь устарел и ничего не делает в новых версиях uwsgi. Я снял флаг, и все по-прежнему работает правильно. Возможно, вы столкнулись с какой-то другой проблемой, которую вам удалось решить с помощью --post-buffering? - person lullis; 10.03.2012
comment
Если проблема в вопросе такая же, как у меня, проблема заключалась в том, что если ваш код Python никогда не читает данные POST (в django это будет доступ к request.POST где-то в вашем представлении), тогда все облажается вверх. Если вы скажете UWSGI буферизовать данные POST с параметром --post-buffering 1, как говорит roberto, ваши запросы POST не будут ошибочными независимо от того, что вы делаете в своем представлении. - person freb; 11.08.2012

После удачной находки в дальнейших исследованиях (http://answerpot.com/showthread.php?577619-Several%20Bugs/Page2) я нашел кое-что, что помогло...

Предоставление параметра uwsgi_pass_request_body off; в конфигурации Nginx решает эту проблему...

person Ulf    schedule 19.10.2010
comment
Это не работает, если вашему приложению действительно нужны данные POST, верно? - person ehabkost; 18.02.2011
comment
Да, это не пройдет через данные сообщения в uwsgi. Вместо этого следует включить постбуферизацию. - person Derrick Petzold; 22.09.2012