【问题标题】:Nginx connection reset, response from uWsgi lostNginx 连接重置,uWsgi 的响应丢失
【发布时间】:2011-04-27 14:18:52
【问题描述】:

我有一个通过 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)

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"

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

有人知道吗?

【问题讨论】:

标签: django nginx uwsgi


【解决方案1】:

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

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

【讨论】:

  • 如果您的应用确实需要 POST 数据,这不起作用,对吧?
  • 是的,这不会将帖子数据传递到 uwsgi。相反,应该打开后缓冲。
【解决方案2】:

我遇到了同样的问题,但在我的情况下,我无法禁用“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()

【讨论】:

  • 这实际上也对我有用(在我的 Flask 项目中)。基本上你需要在回复之前阅读 POST。
  • @VictorFarazdagi 你是如何在 Flask 中做到这一点的?
  • 这是我刚刚解决这个令人讨厌的问题的方法:response.data
  • @roberto 的答案是正确的。否则,大型 POST 将存储在内存中,而不是缓冲到磁盘。
【解决方案3】:

--post-buffering 1 传递给uwsgi

这会自动缓冲所有的http body > 1 byte

问题是由 nginx 管理上游断线的方式引发的

【讨论】:

  • FWIW,@roberto 是 uwsgi 的作者。
  • 这确实是正确答案。它是 uwsgi 的一个选项,您可能希望将它与 --limit-post 结合使用。 projects.unbit.it/uwsgi/wiki/Doc
  • 我遇到了类似的问题(只是它与 POST 无关)。尝试了后缓冲和@ehabkost 的ForcePostHandler,但没有运气。这让我发疯了,请帮助! stackoverflow.com/questions/18667370/…
  • 没关系!我能够通过将buffer-size = 8192 添加到uwsgi 来解决问题。男孩,这很难弄清楚...
  • 这不是一个大的性能问题吗? uWSGI 的文档说这将保存所有大于指定限制的 HTTP 正文。将每个 POST 请求的正文保存到磁盘可能是一个问题。
【解决方案4】:

我也面临同样的问题。我尝试了上述所有解决方案,但它们都不起作用。在我的情况下,忽略响应正文根本不是一种选择。

显然这是nginx and uwsgi when dealing with POST requests whose response is smaller than 4052 bytes的一个错误

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

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

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

$ uwsgi --version
uWSGI 0.9.7

【讨论】:

  • 感谢您的回答。只是将“--pep3333-input”添加到 uwsgi 并没有解决它。我还必须添加此处引用的“--post-buffering 4096”:comments.gmane.org/gmane.comp.python.wsgi.uwsgi.general/812
  • 根据 Roberto 的说法,--pep3333-input 现在已经过时并且在新版本的 uwsgi 上没有任何作用。我删除了标志,事情仍然正常运行。也许您正面临着其他一些您设法通过--post-buffering 解决的问题?
  • 如果问题中的问题与我遇到的问题相同,那么问题是如果您的 python 代码从不读取 POST 数据(在 django 中,这将访问 request.POST 的某处你的观点),然后事情就搞砸了。如果你告诉 UWSGI 使用 roberto 所说的 --post-buffering 1 参数缓冲 POST 数据,那么无论你在视图中做什么,你的 POST 请求都不会出错。
猜你喜欢
  • 2012-10-15
  • 1970-01-01
  • 1970-01-01
  • 2020-04-29
  • 2018-06-12
  • 2019-03-03
  • 2017-12-06
  • 1970-01-01
  • 2023-04-01
相关资源
最近更新 更多