Nginx连接重置,uWsgi的响应丢失

Ulf*_*Ulf 21 django nginx uwsgi

我有一个通过Nginx和uWsgi托管的django应用程序.在某个非常简单的请求中,我得到了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)
Run Code Online (Sandbox Code Playgroud)

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"
Run Code Online (Sandbox Code Playgroud)

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"
Run Code Online (Sandbox Code Playgroud)

本质上,如果我使用POST,Nginx某处会丢失响应,如果我使用GET则不会这样.

有谁知道这件事?

小智 25

传递--post-buffering 1给uwsgi

这将自动缓冲所有http body> 1个字节

nginx管理上游断开连接的方式引发了这个问题

  • 但这不是一个重大的性能问题吗?uWSGI的doc说这将保存所有超过指定限制的HTTP主体.将每个POST请求的正文保存到磁盘可能是个问题. (5认同)
  • FWIW,@ roberto是uwsgi的作者. (2认同)

eha*_*ost 5

我遇到了同样的问题,但在我的情况下,我不能禁用"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()
Run Code Online (Sandbox Code Playgroud)

  • 这实际上也适用于我(在我的情况下与Flask项目).基本上你需要在响应之前阅读POST. (2认同)

lul*_*lis 5

我面临同样的问题.我尝试了上面的所有解决方案,但他们没有工作.在我的情况下忽略响应主体根本不是一个选项.

显然,当处理响应小于4052字节的POST请求时,它是nginx和uwsgi的错误

为我解决的是将"--pep3333-input"添加到uwsgi的参数列表中.之后,所有POST都会正确返回.

我正在使用的nginx/uwsgi的版本:

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

$ uwsgi --version
uWSGI 0.9.7
Run Code Online (Sandbox Code Playgroud)


Ulf*_*Ulf 1

在进一步研究中幸运地发现(http://answerpot.com/showthread.php?577619-Several%20Bugs/Page2)后,我发现了一些有用的东西......

uwsgi_pass_request_body off;在 Nginx conf 中提供参数可以解决这个问题...

  • 如果您的应用程序实际上需要 POST 数据,这不起作用,对吗? (7认同)
  • 是的,这不会将发布数据传递到 uwsgi。相反,应该打开后缓冲。 (2认同)